From f2f2ea8a0f57c12c56cb8065d3db2a948e598e6a Mon Sep 17 00:00:00 2001 From: Icedcocon Date: Fri, 5 May 2023 18:56:08 +0800 Subject: [PATCH 1/4] add:proxy --- ihub/pkg/api/api.go | 5 + ihub/pkg/config/config.go | 2 +- ihub/pkg/constants/constants.go | 5 + ihub/pkg/db/db.go | 27 +++- ihub/pkg/handler/handler.go | 221 +++++++++++++++++++++++--------- ihub/pkg/midware/midware.go | 16 ++- ihub/pkg/utils/utils.go | 53 ++++++-- 7 files changed, 249 insertions(+), 80 deletions(-) diff --git a/ihub/pkg/api/api.go b/ihub/pkg/api/api.go index ba9b4c6..055bd06 100644 --- a/ihub/pkg/api/api.go +++ b/ihub/pkg/api/api.go @@ -6,3 +6,8 @@ type Reply struct { Message string `json:"message"` Data string `json:"data"` } + +type ValiReply struct { + Code int `json:"code"` + Data map[string]string `json:"data"` +} diff --git a/ihub/pkg/config/config.go b/ihub/pkg/config/config.go index 3973a27..69c9273 100644 --- a/ihub/pkg/config/config.go +++ b/ihub/pkg/config/config.go @@ -57,7 +57,7 @@ type ApproveConfig struct { ModuleOperateMapAdmin map[string][]string `yaml:"moduleOperateMapAdmin"` ModuleOperateMapGroup map[string][]string `yaml:"moduleOperateMapGroup"` AppstoreTransMap map[string]string `yaml:"appstoreTransMap"` - OuterServicePortMap map[string]string `yaml:"outerServicePortMap"` + OuterServicePortMap map[string]int `yaml:"outerServicePortMap"` } var gConfig Configuration diff --git a/ihub/pkg/constants/constants.go b/ihub/pkg/constants/constants.go index 1b324f6..2f2ee25 100644 --- a/ihub/pkg/constants/constants.go +++ b/ihub/pkg/constants/constants.go @@ -2,9 +2,11 @@ package constants // Context Parameters const Destination = "Destination" +const ClusterId = "ClusterId" const ClusterName = "ClusterName" const ClusterDomain = "ClusterDomain" const NeedApprove = "NeedApprove" +const ApproveRole = "ApproveRole" // const Role = "Role" @@ -25,3 +27,6 @@ const RunmodeIn = "in" const ClusterStatusReseting = 2 const ClusterStatusResetSucceed = 1 const ClusterStatusResetFailed = 0 + +// ApproveStatus +const ApproveStatusApproving = "APPROVING" diff --git a/ihub/pkg/db/db.go b/ihub/pkg/db/db.go index f771d03..1af93b7 100644 --- a/ihub/pkg/db/db.go +++ b/ihub/pkg/db/db.go @@ -235,11 +235,36 @@ func GetOperatorid(moduleId int, operateName string) ([]Operatorid, error) { return operatorid, nil } +// ApproveInf . +type ApproveInf struct { + ID int `db:"id, omitempty"` + ResourceInfo string `db:"resource_info"` + Createtime time.Time `db:"createtime"` + Userid int `db:"userid"` + Type string `db:"type"` + Status string `db:"status"` + Cluasterid int `db:"clusterid"` + Advice string `db:"advice"` + Groupid int `db:"groupid"` + UserRole int `db:"user_role"` + ModuleName string `db:"module_name"` + URL string `db:"url"` + Method string `db:"method"` + OperateName string `db:"operate_name"` + ResourceDetail string `db:"resource_detail"` + Headers string `db:"headers"` + ApproveRole int `db:"approve_role"` + ApproveResult string `db:"approve_result"` + ApproveTime time.Time `db:"approve_time"` + IsDelete int `db:"is_delete"` + IsApproveDelete int `db:"is_approve_delete"` +} + // 向 approve_inf 插入一条记录 // resource_info resource_detail headers createtime userid module_name operate_name status clusterid // user_role url method approve_role group_id type // 其中 createtime 为当前时间, 使用SQL函数NOW()获取 -func InsertApproveInf(resourceInfo string, resourceDetail string, headers string, userId int, moduleName string, operateName string, status string, clusterId int, userRole string, url string, method string, approveRole string, groupId int, approveType string) error { +func InsertApproveInf(resourceInfo []byte, resourceDetail []byte, headers []byte, userId int, moduleName string, operateName string, status string, clusterId int, userRole int, url string, method string, approveRole int, groupId int, approveType string) error { // 根据 approve_inf 表查询 req := DBInstance.SQL(). InsertInto("approve_inf"). diff --git a/ihub/pkg/handler/handler.go b/ihub/pkg/handler/handler.go index be703dd..4d94f28 100644 --- a/ihub/pkg/handler/handler.go +++ b/ihub/pkg/handler/handler.go @@ -1,8 +1,11 @@ package handler import ( + "encoding/json" "ihub/pkg/api" - mydb "ihub/pkg/db" + "ihub/pkg/config" + "ihub/pkg/constants" + "ihub/pkg/db" "ihub/pkg/utils" "net/http" "net/http/httputil" @@ -22,73 +25,175 @@ func Health(c *gin.Context) { } func Proxy(c *gin.Context) { - // 从请求头中获取X-Cluster-Name,该请求头中包含了当前请求需要访问的集群名称。 - // 如果请求头中不包含X-Cluster-Name,则返回一个错误信息。 - v, ok := c.Request.Header["X-Cluster-Name"] - if !ok { - rp := api.Reply{ - Code: 1, - Message: "缺少集群名称", - Data: "", - } - c.JSON(http.StatusOK, rp) - return + // 判断是集群内还是集群外服务 + destination, _ := c.Get(constants.Destination) + // 判断是否需要审批 + needApprove, _ := c.Get(constants.NeedApprove) + runmode := config.GetConfig().Runmode + + clusterDomain, exists := c.Get(constants.ClusterDomain) + if !exists { + clusterDomain = "" + } + module := c.Param("module") + endpoint := c.Param("endpoint") + // 如果是应用商店接口,需要进行接口转换,如去掉v1/helm、v1/store等 + if _, ok := config.GetConfig().ApproveMap.AppstoreTransMap[endpoint]; ok { + endpoint = config.GetConfig().ApproveMap.AppstoreTransMap[endpoint] } - // 根据集群名称获取对应的域名 - // domain, err := mydb.GetDomainByClusterName(v[0]) - // domain, _, err := mydb.GetDomainIdByClusterName(v[0]) - nameDomainIdList, err := mydb.GetDomainIdByClusterName(v[0]) - domain := nameDomainIdList[0].Domain - if err != nil { - rp := api.Reply{ - Code: 1, - Message: err.Error(), - Data: "", + // 重构url + targetURL, realPath := utils.MakeURL( + destination.(string), + clusterDomain.(string), + module, + endpoint, + runmode, + ) + + if needApprove.(bool) && destination.(string) == runmode { + // 添加审批 + // vali调用 + valiUrl := utils.MakeValiURL(targetURL, module, endpoint) + req := c.Request + method := req.Method + remote, err := url.Parse(valiUrl) + if err != nil { + rp := api.Reply{ + Code: 1, + Message: err.Error(), + Data: "", + } + c.JSON(http.StatusOK, rp) + return + } + // req.Header = c.Request.Header + req.Host = remote.Host + req.URL.Scheme = remote.Scheme + req.URL.Host = remote.Host + req.URL.Path = remote.Path + res, err := (&http.Client{}).Do(req) + if res == nil || err != nil { + rp := api.Reply{ + Code: 1, + Message: err.Error(), + Data: "", + } + c.JSON(http.StatusOK, rp) + return + } + defer res.Body.Close() // ??? + + // 读取响应体 + resourceDetail := map[string]interface{}{} + err = json.NewDecoder(res.Body).Decode(&resourceDetail) + //body, err := httputil.DumpResponse(res, true) + if err != nil { + rp := api.Reply{ + Code: 1, + Message: err.Error(), + Data: "", + } + c.JSON(http.StatusOK, rp) + return } - c.JSON(http.StatusOK, rp) - return - } - // 获取目标URL和真实路径 - // c.Param("proxyPath")获取请求路径中的proxyPath参数,如localhost:8080/api/v1/ - // proxyPath = /完整路径(fullPath) = /模块名称(moudle)/真实路径(realPath) - // 目标URL(targetURL),格式为http://模块名称.default.域名 + // 从响应体中读取信息 + code := resourceDetail["code"].(int) + data := resourceDetail["data"].(map[string]interface{}) + resourceInfo := data["resource_info"].(map[string]interface{}) + if code != 0 { + rp := api.Reply{ + Code: 1, + Message: "审批失败", + Data: "", + } + c.JSON(http.StatusOK, rp) + return + } - targetURL, realPath := utils.MakeURL(domain, c.Param("proxyPath")) + var okList bool + userid, ok := data["userid"] + okList = ok + userRole, ok := data["user_role"] + okList = okList && ok + groupid, ok := data["groupid"] + okList = okList && ok + approvetype, ok := data["type"] + okList = okList && ok + username, ok := data["username"] + okList = okList && ok + groupname, ok := data["groupname"] + okList = okList && ok + nsid, ok := data["nsid"] + okList = okList && ok + if !okList { + rp := api.Reply{ + Code: 1, + Message: "审批返回值缺少字段", + Data: "", + } + c.JSON(http.StatusOK, rp) + return + } + + xToken := map[string]map[string]interface{}{ + "user_info": { + "user_id": userid.(int), + "nsid": nsid.(string), + "groupid": groupid.(string), + "username": username.(string), + "groupname": groupname.(string), + "user_role": userRole.(string), + }, + } + // 转为json + xTokenJson, _ := json.Marshal(xToken) + resourceInfoJson, _ := json.Marshal(resourceInfo) + resourceDetailJson, _ := json.Marshal(resourceDetail) + clusterId, _ := c.Get(constants.ClusterId) + approveRole, _ := c.Get(constants.ApproveRole) + // json_to_str? + db.InsertApproveInf(resourceInfoJson, resourceDetailJson, xTokenJson, userid.(int), module, endpoint, constants.ApproveStatusApproving, clusterId.(int), userRole.(int), targetURL, method, approveRole.(int), groupid.(int), approvetype.(string)) - // Parse方法将字符串解析为URL结构体,并返回一个指向URL结构体的指针和一个错误值。 - remote, err := url.Parse(targetURL) - if err != nil { rp := api.Reply{ - Code: 1, - Message: err.Error(), + Code: 0, + Message: "审批中", Data: "", } c.JSON(http.StatusOK, rp) - return + } else { + // Parse方法将字符串解析为URL结构体,并返回一个指向URL结构体的指针和一个错误值。 + remote, err := url.Parse(targetURL) + if err != nil { + rp := api.Reply{ + Code: 1, + Message: err.Error(), + Data: "", + } + c.JSON(http.StatusOK, rp) + return + } + proxy := httputil.NewSingleHostReverseProxy(remote) + // Director属性是一个函数,该函数用于修改请求的属性,例如修改请求头、请求路径等。 + // 该函数的第一个参数是一个指向http.Request类型的指针,用于获取请求的属性。 + // 函数体中将请求头、请求路径等属性修改为目标URL的属性。 + proxy.Director = func(req *http.Request) { + // Header属性是一个map,用于存储请求头(Headers) + req.Header = c.Request.Header + // Host属性是请求头中的Host字段,用于指定请求的主机名(模块名称.default.域名),会解析为IP地址。 + req.Host = remote.Host + // Scheme属性是请求头中的Scheme字段,用于指定请求的协议(http、https) + req.URL.Scheme = remote.Scheme + // URL.Host属性是请求头中的Host字段,用于指定请求的主机名(模块名称.default.域名) + req.URL.Host = remote.Host + // URL.Path属性是请求头中的Path字段,用于指定请求的路径。 + req.URL.Path = realPath + } + // ServeHTTP方法用于将请求转发到目标URL + // 第一个参数是一个ResponseWriter类型的对象,用于将响应返回给客户端。 + // 第二个参数是一个指向http.Request类型的指针,用于获取请求的属性,传递给Director函数。 + proxy.ServeHTTP(c.Writer, c.Request) } - // 创建一个httputil.ReverseProxy类型的代理对象,并设置其属性,将请求转发到目标URL - // NewSingleHostReverseProxy的参数是一个指向URL结构体的指针,用于指定目标URL。 - proxy := httputil.NewSingleHostReverseProxy(remote) - // Director属性是一个函数,该函数用于修改请求的属性,例如修改请求头、请求路径等。 - // 该函数的第一个参数是一个指向http.Request类型的指针,用于获取请求的属性。 - // 函数体中将请求头、请求路径等属性修改为目标URL的属性。 - proxy.Director = func(req *http.Request) { - // Header属性是一个map,用于存储请求头(Headers) - req.Header = c.Request.Header - // Host属性是请求头中的Host字段,用于指定请求的主机名(模块名称.default.域名),会解析为IP地址。 - req.Host = remote.Host - // Scheme属性是请求头中的Scheme字段,用于指定请求的协议(http、https) - req.URL.Scheme = remote.Scheme - // URL.Host属性是请求头中的Host字段,用于指定请求的主机名(模块名称.default.域名) - req.URL.Host = remote.Host - // URL.Path属性是请求头中的Path字段,用于指定请求的路径。 - req.URL.Path = realPath - } - // ServeHTTP方法用于将请求转发到目标URL - // 第一个参数是一个ResponseWriter类型的对象,用于将响应返回给客户端。 - // 第二个参数是一个指向http.Request类型的指针,用于获取请求的属性,传递给Director函数。 - proxy.ServeHTTP(c.Writer, c.Request) } diff --git a/ihub/pkg/midware/midware.go b/ihub/pkg/midware/midware.go index 7567383..f24b5e5 100644 --- a/ihub/pkg/midware/midware.go +++ b/ihub/pkg/midware/midware.go @@ -163,8 +163,7 @@ func Approve() gin.HandlerFunc { // 解析URL,获取module和endpoint path = module/endpoint module := c.Param("moudle") - // endpoint := utils.FormatEndpoint(c.Param("proxyPath")) - endpoint := c.Param("proxyPath") + endpoint := c.Param("endpoint") // 如果是应用商店接口,需要进行接口转换,如去掉v1/helm、v1/store等 if _, ok := config.GetConfig().ApproveMap.AppstoreTransMap[endpoint]; ok { endpoint = config.GetConfig().ApproveMap.AppstoreTransMap[endpoint] @@ -174,6 +173,7 @@ func Approve() gin.HandlerFunc { inList, role := inCheckList(module, endpoint) // 如果不在列表,则直接通过 if !inList { + c.Set(constants.NeedApprove, false) c.Next() } @@ -204,6 +204,7 @@ func Approve() gin.HandlerFunc { c.AbortWithStatusJSON(http.StatusOK, rp) } c.Set(constants.NeedApprove, needApprove) + c.Set(constants.ApproveRole, constants.RoleClusterAdmin) c.Next() } else if role == constants.RoleGroupAdmin { // 如果为组管理员 // 获取组Id @@ -225,6 +226,7 @@ func Approve() gin.HandlerFunc { } c.AbortWithStatusJSON(http.StatusOK, rp) } + c.Set(constants.ApproveRole, constants.RoleGroupAdmin) c.Set(constants.NeedApprove, needApprove) c.Next() } @@ -317,6 +319,7 @@ func InOut() gin.HandlerFunc { c.AbortWithStatusJSON(http.StatusOK, rp) } // 设置集群名称、域名、目的地 + c.Set(constants.ClusterId, nameDomainIdList[0].ID) c.Set(constants.ClusterName, clusterName) c.Set(constants.ClusterDomain, nameDomainIdList[0].Domain) c.Set(constants.Destination, constants.DestinationIn) @@ -333,7 +336,7 @@ func InOut() gin.HandlerFunc { c.AbortWithStatusJSON(http.StatusOK, rp) } // 根据集群Id获取集群域名 - nameDomainList, err := db.GetNameDomainByClusterId(clusterId) + nameDomainIdList, err := db.GetNameDomainByClusterId(clusterId) if err != nil { rp := api.Reply{ Code: 999, @@ -343,13 +346,14 @@ func InOut() gin.HandlerFunc { c.AbortWithStatusJSON(http.StatusOK, rp) } //checkDomain - rp, err := checkDomain(nameDomainList) + rp, err := checkDomain(nameDomainIdList) if err != nil { c.AbortWithStatusJSON(http.StatusOK, rp) } // 设置集群名称、域名、目的地 - c.Set(constants.ClusterName, nameDomainList[0].Name) - c.Set(constants.ClusterDomain, nameDomainList[0].Domain) + c.Set(constants.ClusterName, nameDomainIdList[0].Name) + c.Set(constants.ClusterId, nameDomainIdList[0].ID) + c.Set(constants.ClusterDomain, nameDomainIdList[0].Domain) c.Set(constants.Destination, constants.DestinationIn) c.Next() } else { diff --git a/ihub/pkg/utils/utils.go b/ihub/pkg/utils/utils.go index 9733a7f..fa06483 100644 --- a/ihub/pkg/utils/utils.go +++ b/ihub/pkg/utils/utils.go @@ -1,6 +1,9 @@ package utils import ( + "fmt" + "ihub/pkg/config" + "ihub/pkg/constants" "os" "strings" @@ -38,18 +41,40 @@ func DecryptSM2(cipherText []byte, priFileName string) ([]byte, error) { } // 拼接URL -func MakeURL(domain, proxyPath string) (string, string) { - // proxyPath = /完整路径(fullPath) = /模块名称(moudle)/真实路径(realPath) - // 目标URL - targetURL := "http://" - // 去掉proxyPath中的第一个/,得到完整的路径 - fullPath := proxyPath[1:] - // 截取fullPath中直到第一个/的字符串,该字符串即为模块名称 - moudle := fullPath[:strings.Index(fullPath, "/")] - // 拼接目标URL,格式为http://模块名称.default.域名 - targetURL = targetURL + moudle + ".default." + domain - // 截取fullPath中第一个/之后的字符串,该字符串为真实路径 - realPath := fullPath[strings.Index(fullPath, "/"):] - // 返回目标URL和真实路径 - return targetURL, realPath +func MakeURL(destination string, domain string, module string, endpoint string, runmode string) (string, string) { + // 判断URL为集群内还是集群外 + if destination == constants.DestinationOut { + // 拼接集群外URL + // http://localhost:port/endpoints + targetURL := "http://localhost:" + port := config.GetConfig().ApproveMap.OuterServicePortMap[module] + targetURL = targetURL + fmt.Sprint(port) + "/" + endpoint + realPath := "/" + endpoint + return targetURL, realPath + + } else if destination == constants.DestinationIn { + if runmode == constants.RunmodeIn { + // 如果是集群内ihub服务 + // http://模块名称.default.域名/endpoints + targetURL := "http://" + realPath := "/" + endpoint + targetURL = targetURL + module + ".default." + domain + realPath + return targetURL, realPath + } else { + // 如果是集群外ihub服务,则发往集群内ihub服务 + // http://ihub.default.域名/module/endpoints + targetURL := "http://" + "ihub" + ".default." + domain // 待修改 + realPath := "/" + module + "/" + endpoint + targetURL = targetURL + realPath + return targetURL, realPath + } + } else { + return "", "" + } +} + +func MakeValiURL(url string, module string, endpoint string) string { + vali_name := "vali_" + module + "_" + endpoint + vali_url := url[:strings.LastIndex(url, "/")] + "/" + vali_name + return vali_url } From 2508c104424c63929ddc049deb60876d4967f9a9 Mon Sep 17 00:00:00 2001 From: Icedcocon Date: Fri, 5 May 2023 19:36:26 +0800 Subject: [PATCH 2/4] add:auth --- ihub/ihub-config.yaml | 3 +++ ihub/pkg/api/api.go | 21 +++++++++++++++---- ihub/pkg/config/config.go | 15 +++++++------- ihub/pkg/constants/constants.go | 1 + ihub/pkg/midware/midware.go | 36 +++++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 11 deletions(-) diff --git a/ihub/ihub-config.yaml b/ihub/ihub-config.yaml index ace6108..58e2c14 100644 --- a/ihub/ihub-config.yaml +++ b/ihub/ihub-config.yaml @@ -22,6 +22,9 @@ midwares: - midware: "trace" - midware: "inout" - midware: "auth" +ibaseUrl: + ipPort: "100.2.44.60:32000" + path: "/v1/token" approveMap: moduleTransMap: account-server: '{"zh-CN": "用户管理","en-US": "account-server"}' diff --git a/ihub/pkg/api/api.go b/ihub/pkg/api/api.go index 055bd06..e60086d 100644 --- a/ihub/pkg/api/api.go +++ b/ihub/pkg/api/api.go @@ -7,7 +7,20 @@ type Reply struct { Data string `json:"data"` } -type ValiReply struct { - Code int `json:"code"` - Data map[string]string `json:"data"` -} +//type TokenResponse struct { +// ErrCode string `json:"errCode"` +// ErrMessage string `json:"errMessage"` +// ExceptionMsg string `json:"exceptionMsg"` +// Flag bool `json:"flag"` +// ResData struct { +// Account string `json:"account"` +// GroupId string `json:"groupId"` +// GroupName string `json:"groupName"` +// InnerCall bool `json:"innerCall"` +// Ip string `json:"ip"` +// Priority int `json:"priority"` +// RoleType int `json:"roleType"` +// UserId string `json:"userId"` +// UserType int `json:"userType"` +// } `json:"resData"` +//} diff --git a/ihub/pkg/config/config.go b/ihub/pkg/config/config.go index 69c9273..bc928ee 100644 --- a/ihub/pkg/config/config.go +++ b/ihub/pkg/config/config.go @@ -42,13 +42,14 @@ type MidwareConfig struct { // Configuration ... type Configuration struct { - DB DBConfig `yaml:"DB"` - LOG LogConfig `yaml:"log"` - SERVER ServerConfig `yaml:"server"` - CACHE CacheConfig `yaml:"cache"` - Midwares []MidwareConfig `yaml:"midwares"` - Runmode string `yaml:"runmode"` - ApproveMap ApproveConfig `yaml:"approveMap"` + DB DBConfig `yaml:"DB"` + LOG LogConfig `yaml:"log"` + SERVER ServerConfig `yaml:"server"` + CACHE CacheConfig `yaml:"cache"` + Midwares []MidwareConfig `yaml:"midwares"` + Runmode string `yaml:"runmode"` + IbaseUrl map[string]string `yaml:"ibaseUrl"` + ApproveMap ApproveConfig `yaml:"approveMap"` } type ApproveConfig struct { diff --git a/ihub/pkg/constants/constants.go b/ihub/pkg/constants/constants.go index 05c0a28..61c3c3c 100644 --- a/ihub/pkg/constants/constants.go +++ b/ihub/pkg/constants/constants.go @@ -35,6 +35,7 @@ const ApproveStatusApproving = "APPROVING" const ( HTTPHeaderClusterName = "X-Cluster-Name" HTTPHeaderTraceID = "X-Trace-ID" + HTTPHeaderAuthInfo = "X-Auth-Info" ) // Default value for rgm diff --git a/ihub/pkg/midware/midware.go b/ihub/pkg/midware/midware.go index 5844bb2..fc6b305 100644 --- a/ihub/pkg/midware/midware.go +++ b/ihub/pkg/midware/midware.go @@ -2,6 +2,7 @@ package midware import ( "bytes" + "encoding/json" "errors" "fmt" "io" @@ -14,7 +15,9 @@ import ( "ihub/pkg/config" "ihub/pkg/constants" "ihub/pkg/db" + "ihub/pkg/utils" "net/http" + "net/url" "github.com/gin-gonic/gin" "github.com/google/uuid" @@ -115,7 +118,40 @@ func GinLogger() gin.HandlerFunc { // Auth func Auth() gin.HandlerFunc { return func(c *gin.Context) { + ibaseUrl := "http://" + config.GetConfig().IbaseUrl["ipPort"] + config.GetConfig().IbaseUrl["path"] + remote, _ := url.Parse(ibaseUrl) + req := http.Request{ + Method: http.MethodGet, + Host: remote.Host, + URL: remote, + Header: c.Request.Header, + } + resp, err := http.DefaultClient.Do(&req) + if err != nil { + c.AbortWithError(http.StatusInternalServerError, err) + return + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + c.AbortWithError(http.StatusInternalServerError, errors.New("auth failed")) + return + } + respData := map[string]interface{}{} + json.NewDecoder(resp.Body).Decode(&respData) + account := respData["account"].(string) + groupId := respData["groupId"].(string) + groupName := respData["groupName"].(string) + roleType := respData["roleType"].(int) + userId := respData["userId"].(string) + userType := respData["userType"].(int) + xAuthInfo := fmt.Sprintf("account:%s,groupId:%s,groupName:%s,roleType:%d,userId:%s,userType:%d", + account, groupId, groupName, roleType, userId, userType) + // pem文件?? + dbcfg := config.GetConfig().DB + pwdByte, _ := utils.DecryptSM2([]byte(xAuthInfo), dbcfg.SM2PrivateFile) + c.Request.Header.Set(constants.HTTPHeaderAuthInfo, string(pwdByte)) + c.Next() } } From f51b7204669b1bc89fa7507436b360d0d52eefc9 Mon Sep 17 00:00:00 2001 From: Icedcocon Date: Fri, 5 May 2023 19:43:46 +0800 Subject: [PATCH 3/4] fix:base64 encode --- ihub/pkg/midware/midware.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ihub/pkg/midware/midware.go b/ihub/pkg/midware/midware.go index fc6b305..f532cc6 100644 --- a/ihub/pkg/midware/midware.go +++ b/ihub/pkg/midware/midware.go @@ -2,6 +2,7 @@ package midware import ( "bytes" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -15,7 +16,6 @@ import ( "ihub/pkg/config" "ihub/pkg/constants" "ihub/pkg/db" - "ihub/pkg/utils" "net/http" "net/url" @@ -147,9 +147,8 @@ func Auth() gin.HandlerFunc { xAuthInfo := fmt.Sprintf("account:%s,groupId:%s,groupName:%s,roleType:%d,userId:%s,userType:%d", account, groupId, groupName, roleType, userId, userType) - // pem文件?? - dbcfg := config.GetConfig().DB - pwdByte, _ := utils.DecryptSM2([]byte(xAuthInfo), dbcfg.SM2PrivateFile) + // p使用Base64对xAuthInfo进行编码 + pwdByte := base64.StdEncoding.EncodeToString([]byte(xAuthInfo)) c.Request.Header.Set(constants.HTTPHeaderAuthInfo, string(pwdByte)) c.Next() } From 8103f954358548f9cd4359327123e24d78af2390 Mon Sep 17 00:00:00 2001 From: Icedcocon Date: Fri, 5 May 2023 19:48:18 +0800 Subject: [PATCH 4/4] add:vendor --- .../github.com/bytedance/sonic/.gitignore | 52 + .../github.com/bytedance/sonic/.gitmodules | 3 + .../bytedance/sonic/.licenserc.yaml | 24 + .../bytedance/sonic/CODE_OF_CONDUCT.md | 128 + .../bytedance/sonic/CONTRIBUTING.md | 63 + .../vendor/github.com/bytedance/sonic/CREDITS | 0 .../bytedance/sonic/INTRODUCTION.md | 48 + .../vendor/github.com/bytedance/sonic/LICENSE | 201 + .../github.com/bytedance/sonic/Makefile | 112 + .../github.com/bytedance/sonic/README.md | 359 + ihub/vendor/github.com/bytedance/sonic/api.go | 185 + .../bytedance/sonic/ast/api_amd64.go | 126 + .../bytedance/sonic/ast/api_compat.go | 102 + .../github.com/bytedance/sonic/ast/asm.s | 0 .../github.com/bytedance/sonic/ast/decode.go | 430 + .../github.com/bytedance/sonic/ast/encode.go | 259 + .../github.com/bytedance/sonic/ast/error.go | 98 + .../bytedance/sonic/ast/iterator.go | 164 + .../github.com/bytedance/sonic/ast/node.go | 1802 ++ .../github.com/bytedance/sonic/ast/parser.go | 618 + .../github.com/bytedance/sonic/ast/search.go | 30 + .../github.com/bytedance/sonic/ast/sort.go | 206 + .../bytedance/sonic/ast/stubs_go115.go | 55 + .../bytedance/sonic/ast/stubs_go120.go | 55 + .../github.com/bytedance/sonic/bench-arm.sh | 14 + .../bytedance/sonic/bench-large.png | Bin 0 -> 87463 bytes .../bytedance/sonic/bench-small.png | Bin 0 -> 87635 bytes .../github.com/bytedance/sonic/bench.py | 134 + .../github.com/bytedance/sonic/bench.sh | 27 + .../bytedance/sonic/check_branch_name.sh | 10 + .../github.com/bytedance/sonic/compat.go | 131 + .../github.com/bytedance/sonic/decoder/asm.s | 0 .../sonic/decoder/assembler_amd64_go116.go | 1943 ++ .../sonic/decoder/assembler_amd64_go117.go | 1922 ++ .../bytedance/sonic/decoder/compiler.go | 1136 ++ .../bytedance/sonic/decoder/debug.go | 70 + .../bytedance/sonic/decoder/decoder.go | 245 + .../bytedance/sonic/decoder/errors.go | 181 + .../sonic/decoder/generic_amd64_go116.go | 776 + .../sonic/decoder/generic_amd64_go117.go | 772 + .../sonic/decoder/generic_amd64_go117_test.s | 37 + .../sonic/decoder/generic_amd64_test.s | 37 + .../bytedance/sonic/decoder/pools.go | 143 + .../bytedance/sonic/decoder/primitives.go | 46 + .../bytedance/sonic/decoder/stream.go | 217 + .../bytedance/sonic/decoder/stubs_go115.go | 111 + .../bytedance/sonic/decoder/stubs_go120.go | 111 + .../bytedance/sonic/decoder/types.go | 58 + .../bytedance/sonic/decoder/utils.go | 39 + .../github.com/bytedance/sonic/encoder/asm.s | 0 .../sonic/encoder/assembler_amd64_go116.go | 1198 ++ .../sonic/encoder/assembler_amd64_go117.go | 1201 ++ .../bytedance/sonic/encoder/compiler.go | 885 + .../bytedance/sonic/encoder/debug_go116.go | 66 + .../bytedance/sonic/encoder/debug_go117.go | 205 + .../bytedance/sonic/encoder/encoder.go | 311 + .../bytedance/sonic/encoder/errors.go | 65 + .../bytedance/sonic/encoder/mapiter.go | 199 + .../bytedance/sonic/encoder/pools.go | 194 + .../bytedance/sonic/encoder/primitives.go | 168 + .../bytedance/sonic/encoder/sort.go | 206 + .../bytedance/sonic/encoder/stream.go | 84 + .../bytedance/sonic/encoder/stubs_go116.go | 65 + .../bytedance/sonic/encoder/stubs_go117.go | 66 + .../bytedance/sonic/encoder/stubs_go120.go | 66 + .../bytedance/sonic/encoder/types.go | 47 + .../bytedance/sonic/encoder/utils.go | 52 + .../vendor/github.com/bytedance/sonic/go.work | 8 + .../bytedance/sonic/internal/caching/asm.s | 0 .../sonic/internal/caching/fcache.go | 115 + .../sonic/internal/caching/hashing.go | 40 + .../sonic/internal/caching/pcache.go | 173 + .../bytedance/sonic/internal/cpu/features.go | 40 + .../sonic/internal/jit/arch_amd64.go | 67 + .../bytedance/sonic/internal/jit/asm.s | 0 .../sonic/internal/jit/assembler_amd64.go | 269 + .../bytedance/sonic/internal/jit/backend.go | 120 + .../bytedance/sonic/internal/jit/runtime.go | 54 + .../bytedance/sonic/internal/loader/asm.s | 0 .../sonic/internal/loader/funcdata.go | 124 + .../sonic/internal/loader/funcdata_go115.go | 169 + .../sonic/internal/loader/funcdata_go116.go | 175 + .../sonic/internal/loader/funcdata_go118.go | 201 + .../sonic/internal/loader/funcdata_go120.go | 201 + .../bytedance/sonic/internal/loader/loader.go | 74 + .../sonic/internal/loader/loader_windows.go | 111 + .../sonic/internal/native/avx/native_amd64.go | 135 + .../sonic/internal/native/avx/native_amd64.s | 15286 ++++++++++++++ .../native/avx/native_export_amd64.go | 49 + .../internal/native/avx/native_subr_amd64.go | 109 + .../internal/native/avx2/native_amd64.go | 135 + .../sonic/internal/native/avx2/native_amd64.s | 16629 ++++++++++++++++ .../native/avx2/native_export_amd64.go | 49 + .../internal/native/avx2/native_subr_amd64.go | 109 + .../sonic/internal/native/dispatch_amd64.go | 202 + .../sonic/internal/native/dispatch_amd64.s | 137 + .../internal/native/fastfloat_amd64_test.tmpl | 138 + .../internal/native/fastint_amd64_test.tmpl | 151 + .../sonic/internal/native/native_amd64.tmpl | 133 + .../internal/native/native_amd64_test.tmpl | 593 + .../internal/native/native_export_amd64.tmpl | 47 + .../sonic/internal/native/sse/native_amd64.go | 135 + .../sonic/internal/native/sse/native_amd64.s | 15078 ++++++++++++++ .../native/sse/native_export_amd64.go | 49 + .../internal/native/sse/native_subr_amd64.go | 109 + .../sonic/internal/native/types/types.go | 134 + .../bytedance/sonic/internal/resolver/asm.s | 0 .../sonic/internal/resolver/resolver.go | 214 + .../sonic/internal/resolver/stubs.go | 46 + .../bytedance/sonic/internal/rt/asm_amd64.s | 60 + .../bytedance/sonic/internal/rt/asm_arm64.s | 10 + .../bytedance/sonic/internal/rt/fastmem.go | 113 + .../bytedance/sonic/internal/rt/fastvalue.go | 200 + .../bytedance/sonic/internal/rt/gcwb.go | 124 + .../bytedance/sonic/internal/rt/int48.go | 36 + .../bytedance/sonic/internal/rt/stackmap.go | 180 + .../bytedance/sonic/introduction-1.png | Bin 0 -> 57447 bytes .../bytedance/sonic/introduction-2.png | Bin 0 -> 68075 bytes .../bytedance/sonic/loader/funcdata.go | 144 + .../bytedance/sonic/loader/funcdata_go115.go | 541 + .../bytedance/sonic/loader/funcdata_go118.go | 541 + .../bytedance/sonic/loader/funcdata_go120.go | 545 + .../bytedance/sonic/loader/loader.go | 37 + .../bytedance/sonic/loader/loader_go115.go | 33 + .../bytedance/sonic/loader/loader_go118.go | 104 + .../bytedance/sonic/loader/mmap_unix.go | 45 + .../bytedance/sonic/loader/mmap_windows.go | 84 + .../bytedance/sonic/loader/pcdata.go | 100 + .../bytedance/sonic/loader/stubs.go | 35 + .../bytedance/sonic/option/option.go | 78 + .../bytedance/sonic/other-langs.png | Bin 0 -> 96490 bytes .../github.com/bytedance/sonic/sonic.go | 161 + .../bytedance/sonic/unquote/unquote.go | 56 + .../github.com/bytedance/sonic/utf8/utf8.go | 71 + .../github.com/chenzhuoyu/base64x/.gitignore | 43 + .../github.com/chenzhuoyu/base64x/.gitmodules | 3 + .../github.com/chenzhuoyu/base64x/LICENSE | 201 + .../github.com/chenzhuoyu/base64x/Makefile | 28 + .../github.com/chenzhuoyu/base64x/README.md | 4 + .../github.com/chenzhuoyu/base64x/base64x.go | 157 + .../github.com/chenzhuoyu/base64x/cpuid.go | 17 + .../github.com/chenzhuoyu/base64x/faststr.go | 23 + .../chenzhuoyu/base64x/native_amd64.go | 16 + .../chenzhuoyu/base64x/native_amd64.s | 4416 ++++ .../chenzhuoyu/base64x/native_subr_amd64.go | 29 + .../fsnotify/fsnotify/.editorconfig | 12 + .../fsnotify/fsnotify/.gitattributes | 1 + .../github.com/fsnotify/fsnotify/.gitignore | 6 + .../github.com/fsnotify/fsnotify/.mailmap | 2 + .../github.com/fsnotify/fsnotify/CHANGELOG.md | 470 + .../fsnotify/fsnotify/CONTRIBUTING.md | 26 + .../github.com/fsnotify/fsnotify/LICENSE | 25 + .../github.com/fsnotify/fsnotify/README.md | 161 + .../fsnotify/fsnotify/backend_fen.go | 162 + .../fsnotify/fsnotify/backend_inotify.go | 459 + .../fsnotify/fsnotify/backend_kqueue.go | 707 + .../fsnotify/fsnotify/backend_other.go | 66 + .../fsnotify/fsnotify/backend_windows.go | 746 + .../github.com/fsnotify/fsnotify/fsnotify.go | 81 + .../github.com/fsnotify/fsnotify/mkdoc.zsh | 208 + .../fsnotify/fsnotify/system_bsd.go | 8 + .../fsnotify/fsnotify/system_darwin.go | 9 + .../github.com/gin-contrib/sse/.travis.yml | 26 + .../vendor/github.com/gin-contrib/sse/LICENSE | 21 + .../github.com/gin-contrib/sse/README.md | 58 + .../github.com/gin-contrib/sse/sse-decoder.go | 116 + .../github.com/gin-contrib/sse/sse-encoder.go | 110 + .../github.com/gin-contrib/sse/writer.go | 24 + .../github.com/gin-gonic/gin/.gitignore | 7 + .../github.com/gin-gonic/gin/.golangci.yml | 39 + .../github.com/gin-gonic/gin/.goreleaser.yaml | 57 + .../github.com/gin-gonic/gin/AUTHORS.md | 406 + .../github.com/gin-gonic/gin/BENCHMARKS.md | 666 + .../github.com/gin-gonic/gin/CHANGELOG.md | 564 + .../gin-gonic/gin/CODE_OF_CONDUCT.md | 46 + .../github.com/gin-gonic/gin/CONTRIBUTING.md | 13 + ihub/vendor/github.com/gin-gonic/gin/LICENSE | 21 + ihub/vendor/github.com/gin-gonic/gin/Makefile | 77 + .../vendor/github.com/gin-gonic/gin/README.md | 179 + ihub/vendor/github.com/gin-gonic/gin/any.go | 10 + ihub/vendor/github.com/gin-gonic/gin/auth.go | 91 + .../github.com/gin-gonic/gin/binding/any.go | 10 + .../gin-gonic/gin/binding/binding.go | 122 + .../gin/binding/binding_nomsgpack.go | 116 + .../gin/binding/default_validator.go | 97 + .../github.com/gin-gonic/gin/binding/form.go | 62 + .../gin-gonic/gin/binding/form_mapping.go | 403 + .../gin-gonic/gin/binding/header.go | 38 + .../github.com/gin-gonic/gin/binding/json.go | 56 + .../gin-gonic/gin/binding/msgpack.go | 38 + .../gin/binding/multipart_form_mapping.go | 74 + .../gin-gonic/gin/binding/protobuf.go | 41 + .../github.com/gin-gonic/gin/binding/query.go | 21 + .../github.com/gin-gonic/gin/binding/toml.go | 35 + .../github.com/gin-gonic/gin/binding/uri.go | 18 + .../github.com/gin-gonic/gin/binding/xml.go | 33 + .../github.com/gin-gonic/gin/binding/yaml.go | 35 + .../github.com/gin-gonic/gin/codecov.yml | 5 + .../github.com/gin-gonic/gin/context.go | 1220 ++ .../gin-gonic/gin/context_appengine.go | 12 + ihub/vendor/github.com/gin-gonic/gin/debug.go | 101 + .../github.com/gin-gonic/gin/deprecated.go | 21 + ihub/vendor/github.com/gin-gonic/gin/doc.go | 6 + .../vendor/github.com/gin-gonic/gin/errors.go | 175 + ihub/vendor/github.com/gin-gonic/gin/fs.go | 45 + ihub/vendor/github.com/gin-gonic/gin/gin.go | 711 + .../gin/internal/bytesconv/bytesconv.go | 24 + .../gin-gonic/gin/internal/json/go_json.go | 23 + .../gin-gonic/gin/internal/json/json.go | 25 + .../gin-gonic/gin/internal/json/jsoniter.go | 24 + .../gin-gonic/gin/internal/json/sonic.go | 27 + .../vendor/github.com/gin-gonic/gin/logger.go | 270 + ihub/vendor/github.com/gin-gonic/gin/mode.go | 100 + ihub/vendor/github.com/gin-gonic/gin/path.go | 150 + .../github.com/gin-gonic/gin/recovery.go | 174 + .../github.com/gin-gonic/gin/render/any.go | 10 + .../github.com/gin-gonic/gin/render/data.go | 25 + .../github.com/gin-gonic/gin/render/html.go | 92 + .../github.com/gin-gonic/gin/render/json.go | 190 + .../gin-gonic/gin/render/msgpack.go | 44 + .../gin-gonic/gin/render/protobuf.go | 36 + .../github.com/gin-gonic/gin/render/reader.go | 48 + .../gin-gonic/gin/render/redirect.go | 29 + .../github.com/gin-gonic/gin/render/render.go | 41 + .../github.com/gin-gonic/gin/render/text.go | 41 + .../github.com/gin-gonic/gin/render/toml.go | 36 + .../github.com/gin-gonic/gin/render/xml.go | 28 + .../github.com/gin-gonic/gin/render/yaml.go | 36 + .../gin-gonic/gin/response_writer.go | 131 + .../github.com/gin-gonic/gin/routergroup.go | 259 + .../github.com/gin-gonic/gin/test_helpers.go | 24 + ihub/vendor/github.com/gin-gonic/gin/tree.go | 878 + ihub/vendor/github.com/gin-gonic/gin/utils.go | 164 + .../github.com/gin-gonic/gin/version.go | 8 + .../go-playground/locales/.gitignore | 24 + .../go-playground/locales/.travis.yml | 26 + .../github.com/go-playground/locales/LICENSE | 21 + .../go-playground/locales/README.md | 170 + .../locales/currency/currency.go | 311 + .../github.com/go-playground/locales/logo.png | Bin 0 -> 37360 bytes .../github.com/go-playground/locales/rules.go | 293 + .../universal-translator/.gitignore | 25 + .../universal-translator/.travis.yml | 27 + .../universal-translator/LICENSE | 21 + .../universal-translator/Makefile | 18 + .../universal-translator/README.md | 87 + .../universal-translator/errors.go | 148 + .../universal-translator/import_export.go | 274 + .../universal-translator/logo.png | Bin 0 -> 16598 bytes .../universal-translator/translator.go | 420 + .../universal_translator.go | 113 + .../go-playground/validator/v10/.gitignore | 31 + .../go-playground/validator/v10/LICENSE | 22 + .../validator/v10/MAINTAINERS.md | 16 + .../go-playground/validator/v10/Makefile | 18 + .../go-playground/validator/v10/README.md | 338 + .../go-playground/validator/v10/baked_in.go | 2526 +++ .../go-playground/validator/v10/cache.go | 327 + .../validator/v10/country_codes.go | 1132 ++ .../validator/v10/currency_codes.go | 79 + .../go-playground/validator/v10/doc.go | 1401 ++ .../go-playground/validator/v10/errors.go | 275 + .../validator/v10/field_level.go | 120 + .../go-playground/validator/v10/logo.png | Bin 0 -> 13443 bytes .../validator/v10/postcode_regexes.go | 173 + .../go-playground/validator/v10/regexes.go | 131 + .../validator/v10/struct_level.go | 175 + .../validator/v10/translations.go | 11 + .../go-playground/validator/v10/util.go | 288 + .../go-playground/validator/v10/validator.go | 486 + .../validator/v10/validator_instance.go | 699 + .../github.com/go-sql-driver/mysql/.gitignore | 9 + .../github.com/go-sql-driver/mysql/AUTHORS | 117 + .../go-sql-driver/mysql/CHANGELOG.md | 232 + .../github.com/go-sql-driver/mysql/LICENSE | 373 + .../github.com/go-sql-driver/mysql/README.md | 520 + .../github.com/go-sql-driver/mysql/auth.go | 425 + .../github.com/go-sql-driver/mysql/buffer.go | 182 + .../go-sql-driver/mysql/collations.go | 265 + .../go-sql-driver/mysql/conncheck.go | 54 + .../go-sql-driver/mysql/conncheck_dummy.go | 17 + .../go-sql-driver/mysql/connection.go | 650 + .../go-sql-driver/mysql/connector.go | 146 + .../github.com/go-sql-driver/mysql/const.go | 174 + .../github.com/go-sql-driver/mysql/driver.go | 107 + .../github.com/go-sql-driver/mysql/dsn.go | 560 + .../github.com/go-sql-driver/mysql/errors.go | 65 + .../github.com/go-sql-driver/mysql/fields.go | 194 + .../github.com/go-sql-driver/mysql/fuzz.go | 24 + .../github.com/go-sql-driver/mysql/infile.go | 182 + .../go-sql-driver/mysql/nulltime.go | 50 + .../go-sql-driver/mysql/nulltime_go113.go | 40 + .../go-sql-driver/mysql/nulltime_legacy.go | 39 + .../github.com/go-sql-driver/mysql/packets.go | 1349 ++ .../github.com/go-sql-driver/mysql/result.go | 22 + .../github.com/go-sql-driver/mysql/rows.go | 223 + .../go-sql-driver/mysql/statement.go | 220 + .../go-sql-driver/mysql/transaction.go | 31 + .../github.com/go-sql-driver/mysql/utils.go | 868 + .../github.com/goccy/go-json/.codecov.yml | 32 + .../github.com/goccy/go-json/.gitignore | 2 + .../github.com/goccy/go-json/.golangci.yml | 83 + .../github.com/goccy/go-json/CHANGELOG.md | 393 + ihub/vendor/github.com/goccy/go-json/LICENSE | 21 + ihub/vendor/github.com/goccy/go-json/Makefile | 39 + .../vendor/github.com/goccy/go-json/README.md | 529 + ihub/vendor/github.com/goccy/go-json/color.go | 68 + .../vendor/github.com/goccy/go-json/decode.go | 263 + .../goccy/go-json/docker-compose.yml | 13 + .../vendor/github.com/goccy/go-json/encode.go | 326 + ihub/vendor/github.com/goccy/go-json/error.go | 41 + .../internal/decoder/anonymous_field.go | 41 + .../goccy/go-json/internal/decoder/array.go | 174 + .../goccy/go-json/internal/decoder/assign.go | 438 + .../goccy/go-json/internal/decoder/bool.go | 83 + .../goccy/go-json/internal/decoder/bytes.go | 118 + .../goccy/go-json/internal/decoder/compile.go | 487 + .../internal/decoder/compile_norace.go | 29 + .../go-json/internal/decoder/compile_race.go | 37 + .../goccy/go-json/internal/decoder/context.go | 254 + .../goccy/go-json/internal/decoder/float.go | 170 + .../goccy/go-json/internal/decoder/func.go | 146 + .../goccy/go-json/internal/decoder/int.go | 246 + .../go-json/internal/decoder/interface.go | 528 + .../goccy/go-json/internal/decoder/invalid.go | 55 + .../goccy/go-json/internal/decoder/map.go | 280 + .../goccy/go-json/internal/decoder/number.go | 123 + .../goccy/go-json/internal/decoder/option.go | 17 + .../goccy/go-json/internal/decoder/path.go | 670 + .../goccy/go-json/internal/decoder/ptr.go | 96 + .../goccy/go-json/internal/decoder/slice.go | 380 + .../goccy/go-json/internal/decoder/stream.go | 556 + .../goccy/go-json/internal/decoder/string.go | 452 + .../goccy/go-json/internal/decoder/struct.go | 823 + .../goccy/go-json/internal/decoder/type.go | 30 + .../goccy/go-json/internal/decoder/uint.go | 194 + .../internal/decoder/unmarshal_json.go | 104 + .../internal/decoder/unmarshal_text.go | 285 + .../internal/decoder/wrapped_string.go | 73 + .../goccy/go-json/internal/encoder/code.go | 1017 + .../goccy/go-json/internal/encoder/compact.go | 286 + .../go-json/internal/encoder/compiler.go | 928 + .../internal/encoder/compiler_norace.go | 32 + .../go-json/internal/encoder/compiler_race.go | 45 + .../goccy/go-json/internal/encoder/context.go | 105 + .../go-json/internal/encoder/decode_rune.go | 126 + .../goccy/go-json/internal/encoder/encoder.go | 596 + .../goccy/go-json/internal/encoder/indent.go | 211 + .../goccy/go-json/internal/encoder/int.go | 152 + .../goccy/go-json/internal/encoder/map112.go | 9 + .../goccy/go-json/internal/encoder/map113.go | 9 + .../goccy/go-json/internal/encoder/opcode.go | 669 + .../goccy/go-json/internal/encoder/option.go | 47 + .../goccy/go-json/internal/encoder/optype.go | 932 + .../goccy/go-json/internal/encoder/query.go | 135 + .../goccy/go-json/internal/encoder/string.go | 459 + .../go-json/internal/encoder/string_table.go | 415 + .../go-json/internal/encoder/vm/debug_vm.go | 35 + .../goccy/go-json/internal/encoder/vm/hack.go | 9 + .../goccy/go-json/internal/encoder/vm/util.go | 207 + .../goccy/go-json/internal/encoder/vm/vm.go | 4859 +++++ .../internal/encoder/vm_color/debug_vm.go | 35 + .../go-json/internal/encoder/vm_color/hack.go | 9 + .../go-json/internal/encoder/vm_color/util.go | 274 + .../go-json/internal/encoder/vm_color/vm.go | 4859 +++++ .../encoder/vm_color_indent/debug_vm.go | 35 + .../internal/encoder/vm_color_indent/util.go | 296 + .../internal/encoder/vm_color_indent/vm.go | 4859 +++++ .../internal/encoder/vm_indent/debug_vm.go | 35 + .../internal/encoder/vm_indent/hack.go | 9 + .../internal/encoder/vm_indent/util.go | 229 + .../go-json/internal/encoder/vm_indent/vm.go | 4859 +++++ .../goccy/go-json/internal/errors/error.go | 183 + .../goccy/go-json/internal/runtime/rtype.go | 263 + .../go-json/internal/runtime/struct_field.go | 91 + .../goccy/go-json/internal/runtime/type.go | 100 + ihub/vendor/github.com/goccy/go-json/json.go | 371 + .../vendor/github.com/goccy/go-json/option.go | 72 + ihub/vendor/github.com/goccy/go-json/path.go | 84 + ihub/vendor/github.com/goccy/go-json/query.go | 47 + .../vendor/github.com/google/uuid/.travis.yml | 9 + .../github.com/google/uuid/CONTRIBUTING.md | 10 + .../github.com/google/uuid/CONTRIBUTORS | 9 + ihub/vendor/github.com/google/uuid/LICENSE | 27 + ihub/vendor/github.com/google/uuid/README.md | 19 + ihub/vendor/github.com/google/uuid/dce.go | 80 + ihub/vendor/github.com/google/uuid/doc.go | 12 + ihub/vendor/github.com/google/uuid/hash.go | 53 + ihub/vendor/github.com/google/uuid/marshal.go | 38 + ihub/vendor/github.com/google/uuid/node.go | 90 + ihub/vendor/github.com/google/uuid/node_js.go | 12 + .../vendor/github.com/google/uuid/node_net.go | 33 + ihub/vendor/github.com/google/uuid/null.go | 118 + ihub/vendor/github.com/google/uuid/sql.go | 59 + ihub/vendor/github.com/google/uuid/time.go | 123 + ihub/vendor/github.com/google/uuid/util.go | 43 + ihub/vendor/github.com/google/uuid/uuid.go | 294 + .../vendor/github.com/google/uuid/version1.go | 44 + .../vendor/github.com/google/uuid/version4.go | 76 + .../github.com/hashicorp/hcl/.gitignore | 9 + .../github.com/hashicorp/hcl/.travis.yml | 13 + ihub/vendor/github.com/hashicorp/hcl/LICENSE | 354 + ihub/vendor/github.com/hashicorp/hcl/Makefile | 18 + .../vendor/github.com/hashicorp/hcl/README.md | 125 + .../github.com/hashicorp/hcl/appveyor.yml | 19 + .../github.com/hashicorp/hcl/decoder.go | 729 + ihub/vendor/github.com/hashicorp/hcl/hcl.go | 11 + .../github.com/hashicorp/hcl/hcl/ast/ast.go | 219 + .../github.com/hashicorp/hcl/hcl/ast/walk.go | 52 + .../hashicorp/hcl/hcl/parser/error.go | 17 + .../hashicorp/hcl/hcl/parser/parser.go | 532 + .../hashicorp/hcl/hcl/printer/nodes.go | 789 + .../hashicorp/hcl/hcl/printer/printer.go | 66 + .../hashicorp/hcl/hcl/scanner/scanner.go | 652 + .../hashicorp/hcl/hcl/strconv/quote.go | 241 + .../hashicorp/hcl/hcl/token/position.go | 46 + .../hashicorp/hcl/hcl/token/token.go | 219 + .../hashicorp/hcl/json/parser/flatten.go | 117 + .../hashicorp/hcl/json/parser/parser.go | 313 + .../hashicorp/hcl/json/scanner/scanner.go | 451 + .../hashicorp/hcl/json/token/position.go | 46 + .../hashicorp/hcl/json/token/token.go | 118 + ihub/vendor/github.com/hashicorp/hcl/lex.go | 38 + ihub/vendor/github.com/hashicorp/hcl/parse.go | 39 + .../github.com/json-iterator/go/.codecov.yml | 3 + .../github.com/json-iterator/go/.gitignore | 4 + .../github.com/json-iterator/go/.travis.yml | 14 + .../github.com/json-iterator/go/Gopkg.lock | 21 + .../github.com/json-iterator/go/Gopkg.toml | 26 + .../github.com/json-iterator/go/LICENSE | 21 + .../github.com/json-iterator/go/README.md | 85 + .../github.com/json-iterator/go/adapter.go | 150 + .../vendor/github.com/json-iterator/go/any.go | 325 + .../github.com/json-iterator/go/any_array.go | 278 + .../github.com/json-iterator/go/any_bool.go | 137 + .../github.com/json-iterator/go/any_float.go | 83 + .../github.com/json-iterator/go/any_int32.go | 74 + .../github.com/json-iterator/go/any_int64.go | 74 + .../json-iterator/go/any_invalid.go | 82 + .../github.com/json-iterator/go/any_nil.go | 69 + .../github.com/json-iterator/go/any_number.go | 123 + .../github.com/json-iterator/go/any_object.go | 374 + .../github.com/json-iterator/go/any_str.go | 166 + .../github.com/json-iterator/go/any_uint32.go | 74 + .../github.com/json-iterator/go/any_uint64.go | 74 + .../github.com/json-iterator/go/build.sh | 12 + .../github.com/json-iterator/go/config.go | 375 + .../go/fuzzy_mode_convert_table.md | 7 + .../github.com/json-iterator/go/iter.go | 349 + .../github.com/json-iterator/go/iter_array.go | 64 + .../github.com/json-iterator/go/iter_float.go | 342 + .../github.com/json-iterator/go/iter_int.go | 346 + .../json-iterator/go/iter_object.go | 267 + .../github.com/json-iterator/go/iter_skip.go | 130 + .../json-iterator/go/iter_skip_sloppy.go | 163 + .../json-iterator/go/iter_skip_strict.go | 99 + .../github.com/json-iterator/go/iter_str.go | 215 + .../github.com/json-iterator/go/jsoniter.go | 18 + .../github.com/json-iterator/go/pool.go | 42 + .../github.com/json-iterator/go/reflect.go | 337 + .../json-iterator/go/reflect_array.go | 104 + .../json-iterator/go/reflect_dynamic.go | 70 + .../json-iterator/go/reflect_extension.go | 483 + .../json-iterator/go/reflect_json_number.go | 112 + .../go/reflect_json_raw_message.go | 76 + .../json-iterator/go/reflect_map.go | 346 + .../json-iterator/go/reflect_marshaler.go | 225 + .../json-iterator/go/reflect_native.go | 453 + .../json-iterator/go/reflect_optional.go | 129 + .../json-iterator/go/reflect_slice.go | 99 + .../go/reflect_struct_decoder.go | 1097 + .../go/reflect_struct_encoder.go | 211 + .../github.com/json-iterator/go/stream.go | 210 + .../json-iterator/go/stream_float.go | 111 + .../github.com/json-iterator/go/stream_int.go | 190 + .../github.com/json-iterator/go/stream_str.go | 372 + .../github.com/json-iterator/go/test.sh | 12 + .../github.com/klauspost/cpuid/v2/.gitignore | 24 + .../klauspost/cpuid/v2/.goreleaser.yml | 74 + .../klauspost/cpuid/v2/CONTRIBUTING.txt | 35 + .../github.com/klauspost/cpuid/v2/LICENSE | 22 + .../github.com/klauspost/cpuid/v2/README.md | 137 + .../github.com/klauspost/cpuid/v2/cpuid.go | 1070 + .../github.com/klauspost/cpuid/v2/cpuid_386.s | 47 + .../klauspost/cpuid/v2/cpuid_amd64.s | 72 + .../klauspost/cpuid/v2/cpuid_arm64.s | 26 + .../klauspost/cpuid/v2/detect_arm64.go | 246 + .../klauspost/cpuid/v2/detect_ref.go | 14 + .../klauspost/cpuid/v2/detect_x86.go | 35 + .../klauspost/cpuid/v2/featureid_string.go | 185 + .../klauspost/cpuid/v2/os_darwin_arm64.go | 19 + .../klauspost/cpuid/v2/os_linux_arm64.go | 130 + .../klauspost/cpuid/v2/os_other_arm64.go | 17 + .../klauspost/cpuid/v2/os_safe_linux_arm64.go | 7 + .../cpuid/v2/os_unsafe_linux_arm64.go | 10 + .../klauspost/cpuid/v2/test-architectures.sh | 15 + .../github.com/leodido/go-urn/.gitignore | 11 + .../github.com/leodido/go-urn/.travis.yml | 16 + ihub/vendor/github.com/leodido/go-urn/LICENSE | 21 + .../github.com/leodido/go-urn/README.md | 55 + .../github.com/leodido/go-urn/machine.go | 1691 ++ .../github.com/leodido/go-urn/machine.go.rl | 159 + .../vendor/github.com/leodido/go-urn/makefile | 39 + ihub/vendor/github.com/leodido/go-urn/urn.go | 86 + .../magiconair/properties/.gitignore | 6 + .../magiconair/properties/CHANGELOG.md | 205 + .../magiconair/properties/LICENSE.md | 24 + .../magiconair/properties/README.md | 128 + .../magiconair/properties/decode.go | 289 + .../github.com/magiconair/properties/doc.go | 155 + .../magiconair/properties/integrate.go | 35 + .../github.com/magiconair/properties/lex.go | 395 + .../github.com/magiconair/properties/load.go | 293 + .../magiconair/properties/parser.go | 86 + .../magiconair/properties/properties.go | 848 + .../magiconair/properties/rangecheck.go | 31 + .../vendor/github.com/mattn/go-isatty/LICENSE | 9 + .../github.com/mattn/go-isatty/README.md | 50 + ihub/vendor/github.com/mattn/go-isatty/doc.go | 2 + .../github.com/mattn/go-isatty/go.test.sh | 12 + .../github.com/mattn/go-isatty/isatty_bsd.go | 19 + .../mattn/go-isatty/isatty_others.go | 16 + .../mattn/go-isatty/isatty_plan9.go | 23 + .../mattn/go-isatty/isatty_solaris.go | 21 + .../mattn/go-isatty/isatty_tcgets.go | 19 + .../mattn/go-isatty/isatty_windows.go | 125 + .../mitchellh/mapstructure/CHANGELOG.md | 96 + .../github.com/mitchellh/mapstructure/LICENSE | 21 + .../mitchellh/mapstructure/README.md | 46 + .../mitchellh/mapstructure/decode_hooks.go | 279 + .../mitchellh/mapstructure/error.go | 50 + .../mitchellh/mapstructure/mapstructure.go | 1540 ++ .../modern-go/concurrent/.gitignore | 1 + .../modern-go/concurrent/.travis.yml | 14 + .../github.com/modern-go/concurrent/LICENSE | 201 + .../github.com/modern-go/concurrent/README.md | 49 + .../modern-go/concurrent/executor.go | 14 + .../modern-go/concurrent/go_above_19.go | 15 + .../modern-go/concurrent/go_below_19.go | 33 + .../github.com/modern-go/concurrent/log.go | 13 + .../github.com/modern-go/concurrent/test.sh | 12 + .../concurrent/unbounded_executor.go | 119 + .../github.com/modern-go/reflect2/.gitignore | 2 + .../github.com/modern-go/reflect2/.travis.yml | 15 + .../github.com/modern-go/reflect2/Gopkg.lock | 9 + .../github.com/modern-go/reflect2/Gopkg.toml | 31 + .../github.com/modern-go/reflect2/LICENSE | 201 + .../github.com/modern-go/reflect2/README.md | 71 + .../modern-go/reflect2/go_above_118.go | 23 + .../modern-go/reflect2/go_above_19.go | 17 + .../modern-go/reflect2/go_below_118.go | 21 + .../github.com/modern-go/reflect2/reflect2.go | 300 + .../modern-go/reflect2/reflect2_amd64.s | 0 .../modern-go/reflect2/reflect2_kind.go | 30 + .../modern-go/reflect2/relfect2_386.s | 0 .../modern-go/reflect2/relfect2_amd64p32.s | 0 .../modern-go/reflect2/relfect2_arm.s | 0 .../modern-go/reflect2/relfect2_arm64.s | 0 .../modern-go/reflect2/relfect2_mips64x.s | 0 .../modern-go/reflect2/relfect2_mipsx.s | 0 .../modern-go/reflect2/relfect2_ppc64x.s | 0 .../modern-go/reflect2/relfect2_s390x.s | 0 .../modern-go/reflect2/safe_field.go | 58 + .../github.com/modern-go/reflect2/safe_map.go | 101 + .../modern-go/reflect2/safe_slice.go | 92 + .../modern-go/reflect2/safe_struct.go | 29 + .../modern-go/reflect2/safe_type.go | 78 + .../github.com/modern-go/reflect2/type_map.go | 70 + .../modern-go/reflect2/unsafe_array.go | 65 + .../modern-go/reflect2/unsafe_eface.go | 59 + .../modern-go/reflect2/unsafe_field.go | 74 + .../modern-go/reflect2/unsafe_iface.go | 64 + .../modern-go/reflect2/unsafe_link.go | 76 + .../modern-go/reflect2/unsafe_map.go | 130 + .../modern-go/reflect2/unsafe_ptr.go | 46 + .../modern-go/reflect2/unsafe_slice.go | 177 + .../modern-go/reflect2/unsafe_struct.go | 59 + .../modern-go/reflect2/unsafe_type.go | 85 + .../pelletier/go-toml/v2/.dockerignore | 2 + .../pelletier/go-toml/v2/.gitattributes | 4 + .../pelletier/go-toml/v2/.gitignore | 6 + .../pelletier/go-toml/v2/.golangci.toml | 84 + .../pelletier/go-toml/v2/.goreleaser.yaml | 123 + .../pelletier/go-toml/v2/CONTRIBUTING.md | 196 + .../pelletier/go-toml/v2/Dockerfile | 5 + .../github.com/pelletier/go-toml/v2/LICENSE | 21 + .../github.com/pelletier/go-toml/v2/README.md | 563 + .../pelletier/go-toml/v2/SECURITY.md | 19 + .../github.com/pelletier/go-toml/v2/ci.sh | 279 + .../github.com/pelletier/go-toml/v2/decode.go | 550 + .../github.com/pelletier/go-toml/v2/doc.go | 2 + .../github.com/pelletier/go-toml/v2/errors.go | 252 + .../go-toml/v2/internal/characters/ascii.go | 42 + .../go-toml/v2/internal/characters/utf8.go | 199 + .../go-toml/v2/internal/danger/danger.go | 65 + .../go-toml/v2/internal/danger/typeid.go | 23 + .../go-toml/v2/internal/tracker/key.go | 48 + .../go-toml/v2/internal/tracker/seen.go | 356 + .../go-toml/v2/internal/tracker/tracker.go | 1 + .../pelletier/go-toml/v2/localtime.go | 122 + .../pelletier/go-toml/v2/marshaler.go | 1042 + .../github.com/pelletier/go-toml/v2/strict.go | 107 + .../github.com/pelletier/go-toml/v2/toml.abnf | 243 + .../github.com/pelletier/go-toml/v2/types.go | 14 + .../pelletier/go-toml/v2/unmarshaler.go | 1227 ++ .../pelletier/go-toml/v2/unstable/ast.go | 136 + .../pelletier/go-toml/v2/unstable/builder.go | 71 + .../pelletier/go-toml/v2/unstable/doc.go | 3 + .../pelletier/go-toml/v2/unstable/kind.go | 71 + .../pelletier/go-toml/v2/unstable/parser.go | 1147 ++ .../pelletier/go-toml/v2/unstable/scanner.go | 271 + .../github.com/segmentio/fasthash/LICENSE | 21 + .../segmentio/fasthash/fnv1a/hash.go | 121 + .../segmentio/fasthash/fnv1a/hash32.go | 104 + .../github.com/sirupsen/logrus/.gitignore | 4 + .../github.com/sirupsen/logrus/.golangci.yml | 40 + .../github.com/sirupsen/logrus/.travis.yml | 15 + .../github.com/sirupsen/logrus/CHANGELOG.md | 259 + .../vendor/github.com/sirupsen/logrus/LICENSE | 21 + .../github.com/sirupsen/logrus/README.md | 513 + .../github.com/sirupsen/logrus/alt_exit.go | 76 + .../github.com/sirupsen/logrus/appveyor.yml | 14 + .../github.com/sirupsen/logrus/buffer_pool.go | 43 + ihub/vendor/github.com/sirupsen/logrus/doc.go | 26 + .../github.com/sirupsen/logrus/entry.go | 442 + .../github.com/sirupsen/logrus/exported.go | 270 + .../github.com/sirupsen/logrus/formatter.go | 78 + .../github.com/sirupsen/logrus/hooks.go | 34 + .../sirupsen/logrus/json_formatter.go | 128 + .../github.com/sirupsen/logrus/logger.go | 417 + .../github.com/sirupsen/logrus/logrus.go | 186 + .../logrus/terminal_check_appengine.go | 11 + .../sirupsen/logrus/terminal_check_bsd.go | 13 + .../sirupsen/logrus/terminal_check_js.go | 7 + .../logrus/terminal_check_no_terminal.go | 11 + .../logrus/terminal_check_notappengine.go | 17 + .../sirupsen/logrus/terminal_check_solaris.go | 11 + .../sirupsen/logrus/terminal_check_unix.go | 13 + .../sirupsen/logrus/terminal_check_windows.go | 27 + .../sirupsen/logrus/text_formatter.go | 339 + .../github.com/sirupsen/logrus/writer.go | 70 + ihub/vendor/github.com/spf13/afero/.gitignore | 2 + .../vendor/github.com/spf13/afero/LICENSE.txt | 174 + ihub/vendor/github.com/spf13/afero/README.md | 442 + ihub/vendor/github.com/spf13/afero/afero.go | 111 + .../github.com/spf13/afero/appveyor.yml | 10 + .../vendor/github.com/spf13/afero/basepath.go | 223 + .../github.com/spf13/afero/cacheOnReadFs.go | 315 + .../github.com/spf13/afero/const_bsds.go | 23 + .../github.com/spf13/afero/const_win_unix.go | 22 + .../github.com/spf13/afero/copyOnWriteFs.go | 326 + ihub/vendor/github.com/spf13/afero/httpFs.go | 114 + .../spf13/afero/internal/common/adapters.go | 27 + ihub/vendor/github.com/spf13/afero/iofs.go | 298 + ihub/vendor/github.com/spf13/afero/ioutil.go | 240 + ihub/vendor/github.com/spf13/afero/lstater.go | 27 + ihub/vendor/github.com/spf13/afero/match.go | 110 + ihub/vendor/github.com/spf13/afero/mem/dir.go | 37 + .../github.com/spf13/afero/mem/dirmap.go | 43 + .../vendor/github.com/spf13/afero/mem/file.go | 356 + ihub/vendor/github.com/spf13/afero/memmap.go | 409 + ihub/vendor/github.com/spf13/afero/os.go | 113 + ihub/vendor/github.com/spf13/afero/path.go | 106 + .../github.com/spf13/afero/readonlyfs.go | 96 + .../vendor/github.com/spf13/afero/regexpfs.go | 224 + ihub/vendor/github.com/spf13/afero/symlink.go | 55 + .../github.com/spf13/afero/unionFile.go | 331 + ihub/vendor/github.com/spf13/afero/util.go | 330 + ihub/vendor/github.com/spf13/cast/.gitignore | 25 + ihub/vendor/github.com/spf13/cast/LICENSE | 21 + ihub/vendor/github.com/spf13/cast/Makefile | 40 + ihub/vendor/github.com/spf13/cast/README.md | 75 + ihub/vendor/github.com/spf13/cast/cast.go | 176 + ihub/vendor/github.com/spf13/cast/caste.go | 1476 ++ .../spf13/cast/timeformattype_string.go | 27 + .../spf13/jwalterweatherman/.gitignore | 24 + .../spf13/jwalterweatherman/LICENSE | 21 + .../spf13/jwalterweatherman/README.md | 148 + .../jwalterweatherman/default_notepad.go | 111 + .../spf13/jwalterweatherman/log_counter.go | 46 + .../spf13/jwalterweatherman/notepad.go | 225 + ihub/vendor/github.com/spf13/pflag/.gitignore | 2 + .../vendor/github.com/spf13/pflag/.travis.yml | 22 + ihub/vendor/github.com/spf13/pflag/LICENSE | 28 + ihub/vendor/github.com/spf13/pflag/README.md | 296 + ihub/vendor/github.com/spf13/pflag/bool.go | 94 + .../github.com/spf13/pflag/bool_slice.go | 185 + ihub/vendor/github.com/spf13/pflag/bytes.go | 209 + ihub/vendor/github.com/spf13/pflag/count.go | 96 + .../vendor/github.com/spf13/pflag/duration.go | 86 + .../github.com/spf13/pflag/duration_slice.go | 166 + ihub/vendor/github.com/spf13/pflag/flag.go | 1239 ++ ihub/vendor/github.com/spf13/pflag/float32.go | 88 + .../github.com/spf13/pflag/float32_slice.go | 174 + ihub/vendor/github.com/spf13/pflag/float64.go | 84 + .../github.com/spf13/pflag/float64_slice.go | 166 + .../github.com/spf13/pflag/golangflag.go | 105 + ihub/vendor/github.com/spf13/pflag/int.go | 84 + ihub/vendor/github.com/spf13/pflag/int16.go | 88 + ihub/vendor/github.com/spf13/pflag/int32.go | 88 + .../github.com/spf13/pflag/int32_slice.go | 174 + ihub/vendor/github.com/spf13/pflag/int64.go | 84 + .../github.com/spf13/pflag/int64_slice.go | 166 + ihub/vendor/github.com/spf13/pflag/int8.go | 88 + .../github.com/spf13/pflag/int_slice.go | 158 + ihub/vendor/github.com/spf13/pflag/ip.go | 94 + .../vendor/github.com/spf13/pflag/ip_slice.go | 186 + ihub/vendor/github.com/spf13/pflag/ipmask.go | 122 + ihub/vendor/github.com/spf13/pflag/ipnet.go | 98 + ihub/vendor/github.com/spf13/pflag/string.go | 80 + .../github.com/spf13/pflag/string_array.go | 129 + .../github.com/spf13/pflag/string_slice.go | 163 + .../github.com/spf13/pflag/string_to_int.go | 149 + .../github.com/spf13/pflag/string_to_int64.go | 149 + .../spf13/pflag/string_to_string.go | 160 + ihub/vendor/github.com/spf13/pflag/uint.go | 88 + ihub/vendor/github.com/spf13/pflag/uint16.go | 88 + ihub/vendor/github.com/spf13/pflag/uint32.go | 88 + ihub/vendor/github.com/spf13/pflag/uint64.go | 88 + ihub/vendor/github.com/spf13/pflag/uint8.go | 88 + .../github.com/spf13/pflag/uint_slice.go | 168 + .../github.com/spf13/viper/.editorconfig | 15 + ihub/vendor/github.com/spf13/viper/.gitignore | 5 + .../github.com/spf13/viper/.golangci.yaml | 96 + ihub/vendor/github.com/spf13/viper/LICENSE | 21 + ihub/vendor/github.com/spf13/viper/Makefile | 76 + ihub/vendor/github.com/spf13/viper/README.md | 881 + .../github.com/spf13/viper/TROUBLESHOOTING.md | 32 + .../spf13/viper/experimental_logger.go | 11 + ihub/vendor/github.com/spf13/viper/flags.go | 57 + ihub/vendor/github.com/spf13/viper/fs.go | 65 + .../spf13/viper/internal/encoding/decoder.go | 61 + .../viper/internal/encoding/dotenv/codec.go | 61 + .../internal/encoding/dotenv/map_utils.go | 41 + .../spf13/viper/internal/encoding/encoder.go | 60 + .../spf13/viper/internal/encoding/error.go | 7 + .../viper/internal/encoding/hcl/codec.go | 40 + .../viper/internal/encoding/ini/codec.go | 99 + .../viper/internal/encoding/ini/map_utils.go | 74 + .../internal/encoding/javaproperties/codec.go | 86 + .../encoding/javaproperties/map_utils.go | 74 + .../viper/internal/encoding/json/codec.go | 17 + .../viper/internal/encoding/toml/codec.go | 16 + .../viper/internal/encoding/yaml/codec.go | 14 + ihub/vendor/github.com/spf13/viper/logger.go | 77 + ihub/vendor/github.com/spf13/viper/util.go | 217 + ihub/vendor/github.com/spf13/viper/viper.go | 2154 ++ .../github.com/spf13/viper/viper_go1_15.go | 57 + .../github.com/spf13/viper/viper_go1_16.go | 32 + ihub/vendor/github.com/spf13/viper/watch.go | 12 + .../spf13/viper/watch_unsupported.go | 32 + ihub/vendor/github.com/subosito/gotenv/.env | 1 + .../github.com/subosito/gotenv/.env.invalid | 1 + .../github.com/subosito/gotenv/.gitignore | 4 + .../github.com/subosito/gotenv/.golangci.yaml | 7 + .../github.com/subosito/gotenv/CHANGELOG.md | 68 + .../vendor/github.com/subosito/gotenv/LICENSE | 21 + .../github.com/subosito/gotenv/README.md | 129 + .../github.com/subosito/gotenv/gotenv.go | 381 + ihub/vendor/github.com/tjfoc/gmsm/LICENSE | 201 + ihub/vendor/github.com/tjfoc/gmsm/sm2/p256.go | 1182 ++ ihub/vendor/github.com/tjfoc/gmsm/sm2/sm2.go | 674 + .../vendor/github.com/tjfoc/gmsm/sm2/utils.go | 59 + ihub/vendor/github.com/tjfoc/gmsm/sm3/ifile | 1 + ihub/vendor/github.com/tjfoc/gmsm/sm3/sm3.go | 259 + ihub/vendor/github.com/tjfoc/gmsm/x509/ber.go | 248 + .../github.com/tjfoc/gmsm/x509/cert_pool.go | 229 + .../github.com/tjfoc/gmsm/x509/pkcs1.go | 132 + .../github.com/tjfoc/gmsm/x509/pkcs7.go | 971 + .../github.com/tjfoc/gmsm/x509/pkcs8.go | 371 + .../github.com/tjfoc/gmsm/x509/utils.go | 295 + .../github.com/tjfoc/gmsm/x509/verify.go | 568 + .../vendor/github.com/tjfoc/gmsm/x509/x509.go | 2464 +++ .../twitchyliquid64/golang-asm/LICENSE | 27 + .../golang-asm/asm/arch/arch.go | 716 + .../golang-asm/asm/arch/arm.go | 257 + .../golang-asm/asm/arch/arm64.go | 350 + .../golang-asm/asm/arch/mips.go | 72 + .../golang-asm/asm/arch/ppc64.go | 102 + .../golang-asm/asm/arch/riscv64.go | 28 + .../golang-asm/asm/arch/s390x.go | 81 + .../twitchyliquid64/golang-asm/bio/buf.go | 148 + .../golang-asm/bio/buf_mmap.go | 62 + .../golang-asm/bio/buf_nommap.go | 11 + .../twitchyliquid64/golang-asm/bio/must.go | 43 + .../twitchyliquid64/golang-asm/dwarf/dwarf.go | 1650 ++ .../golang-asm/dwarf/dwarf_defs.go | 493 + .../golang-asm/goobj/builtin.go | 45 + .../golang-asm/goobj/builtinlist.go | 245 + .../golang-asm/goobj/funcinfo.go | 233 + .../golang-asm/goobj/objfile.go | 871 + .../golang-asm/obj/abi_string.go | 16 + .../golang-asm/obj/addrtype_string.go | 16 + .../golang-asm/obj/arm/a.out.go | 410 + .../golang-asm/obj/arm/anames.go | 144 + .../golang-asm/obj/arm/anames5.go | 77 + .../golang-asm/obj/arm/asm5.go | 3096 +++ .../golang-asm/obj/arm/list5.go | 124 + .../golang-asm/obj/arm/obj5.go | 784 + .../golang-asm/obj/arm64/a.out.go | 1033 + .../golang-asm/obj/arm64/anames.go | 512 + .../golang-asm/obj/arm64/anames7.go | 100 + .../golang-asm/obj/arm64/asm7.go | 7140 +++++++ .../golang-asm/obj/arm64/doc.go | 249 + .../golang-asm/obj/arm64/list7.go | 288 + .../golang-asm/obj/arm64/obj7.go | 998 + .../golang-asm/obj/arm64/sysRegEnc.go | 895 + .../twitchyliquid64/golang-asm/obj/data.go | 200 + .../twitchyliquid64/golang-asm/obj/dwarf.go | 690 + .../twitchyliquid64/golang-asm/obj/go.go | 16 + .../twitchyliquid64/golang-asm/obj/inl.go | 131 + .../twitchyliquid64/golang-asm/obj/ld.go | 85 + .../twitchyliquid64/golang-asm/obj/line.go | 30 + .../twitchyliquid64/golang-asm/obj/link.go | 771 + .../golang-asm/obj/mips/a.out.go | 481 + .../golang-asm/obj/mips/anames.go | 135 + .../golang-asm/obj/mips/anames0.go | 45 + .../golang-asm/obj/mips/asm0.go | 2108 ++ .../golang-asm/obj/mips/list0.go | 83 + .../golang-asm/obj/mips/obj0.go | 1457 ++ .../twitchyliquid64/golang-asm/obj/objfile.go | 755 + .../twitchyliquid64/golang-asm/obj/pass.go | 176 + .../twitchyliquid64/golang-asm/obj/pcln.go | 413 + .../twitchyliquid64/golang-asm/obj/plist.go | 314 + .../golang-asm/obj/ppc64/a.out.go | 1032 + .../golang-asm/obj/ppc64/anames.go | 615 + .../golang-asm/obj/ppc64/anames9.go | 51 + .../golang-asm/obj/ppc64/asm9.go | 5367 +++++ .../golang-asm/obj/ppc64/doc.go | 244 + .../golang-asm/obj/ppc64/list9.go | 104 + .../golang-asm/obj/ppc64/obj9.go | 1278 ++ .../golang-asm/obj/riscv/anames.go | 258 + .../golang-asm/obj/riscv/cpu.go | 644 + .../golang-asm/obj/riscv/inst.go | 459 + .../golang-asm/obj/riscv/list.go | 33 + .../golang-asm/obj/riscv/obj.go | 1999 ++ .../golang-asm/obj/s390x/a.out.go | 1003 + .../golang-asm/obj/s390x/anames.go | 720 + .../golang-asm/obj/s390x/anamesz.go | 39 + .../golang-asm/obj/s390x/asmz.go | 5043 +++++ .../golang-asm/obj/s390x/condition_code.go | 126 + .../golang-asm/obj/s390x/listz.go | 73 + .../golang-asm/obj/s390x/objz.go | 735 + .../golang-asm/obj/s390x/rotate.go | 47 + .../golang-asm/obj/s390x/vector.go | 1069 + .../twitchyliquid64/golang-asm/obj/sym.go | 421 + .../golang-asm/obj/textflag.go | 54 + .../twitchyliquid64/golang-asm/obj/util.go | 598 + .../golang-asm/obj/wasm/a.out.go | 331 + .../golang-asm/obj/wasm/anames.go | 208 + .../golang-asm/obj/wasm/wasmobj.go | 1185 ++ .../golang-asm/obj/x86/a.out.go | 423 + .../golang-asm/obj/x86/aenum.go | 1609 ++ .../golang-asm/obj/x86/anames.go | 1607 ++ .../golang-asm/obj/x86/asm6.go | 5446 +++++ .../golang-asm/obj/x86/avx_optabs.go | 4628 +++++ .../golang-asm/obj/x86/evex.go | 382 + .../golang-asm/obj/x86/list6.go | 264 + .../golang-asm/obj/x86/obj6.go | 1261 ++ .../golang-asm/obj/x86/ytab.go | 44 + .../golang-asm/objabi/autotype.go | 38 + .../twitchyliquid64/golang-asm/objabi/flag.go | 162 + .../golang-asm/objabi/funcdata.go | 54 + .../golang-asm/objabi/funcid.go | 100 + .../twitchyliquid64/golang-asm/objabi/head.go | 109 + .../twitchyliquid64/golang-asm/objabi/line.go | 114 + .../twitchyliquid64/golang-asm/objabi/path.go | 41 + .../golang-asm/objabi/reloctype.go | 269 + .../golang-asm/objabi/reloctype_string.go | 17 + .../golang-asm/objabi/stack.go | 33 + .../golang-asm/objabi/symkind.go | 79 + .../golang-asm/objabi/symkind_string.go | 41 + .../golang-asm/objabi/typekind.go | 40 + .../twitchyliquid64/golang-asm/objabi/util.go | 203 + .../twitchyliquid64/golang-asm/src/pos.go | 470 + .../twitchyliquid64/golang-asm/src/xpos.go | 176 + .../twitchyliquid64/golang-asm/sys/arch.go | 187 + .../golang-asm/sys/supported.go | 116 + .../golang-asm/unsafeheader/unsafeheader.go | 37 + .../ugorji/go/codec/0_importpath.go | 7 + .../vendor/github.com/ugorji/go/codec/LICENSE | 22 + .../github.com/ugorji/go/codec/README.md | 284 + .../vendor/github.com/ugorji/go/codec/binc.go | 1319 ++ .../github.com/ugorji/go/codec/build.sh | 370 + .../vendor/github.com/ugorji/go/codec/cbor.go | 957 + .../github.com/ugorji/go/codec/codecgen.go | 17 + .../github.com/ugorji/go/codec/decimal.go | 499 + .../github.com/ugorji/go/codec/decode.go | 2376 +++ ihub/vendor/github.com/ugorji/go/codec/doc.go | 227 + .../github.com/ugorji/go/codec/encode.go | 1524 ++ .../ugorji/go/codec/fast-path.generated.go | 6157 ++++++ .../ugorji/go/codec/fast-path.go.tmpl | 555 + .../ugorji/go/codec/fast-path.not.go | 41 + .../ugorji/go/codec/gen-dec-array.go.tmpl | 90 + .../ugorji/go/codec/gen-dec-map.go.tmpl | 58 + .../ugorji/go/codec/gen-enc-chan.go.tmpl | 27 + .../ugorji/go/codec/gen-helper.generated.go | 294 + .../ugorji/go/codec/gen-helper.go.tmpl | 273 + .../ugorji/go/codec/gen.generated.go | 192 + ihub/vendor/github.com/ugorji/go/codec/gen.go | 2876 +++ .../go/codec/goversion_arrayof_gte_go15.go | 15 + .../go/codec/goversion_arrayof_lt_go15.go | 20 + .../go/codec/goversion_fmt_time_gte_go15.go | 13 + .../go/codec/goversion_fmt_time_lt_go15.go | 16 + .../goversion_growslice_unsafe_gte_go120.go | 28 + .../goversion_growslice_unsafe_lt_go120.go | 16 + .../go/codec/goversion_makemap_lt_go110.go | 13 + .../goversion_makemap_not_unsafe_gte_go110.go | 14 + .../goversion_makemap_unsafe_gte_go110.go | 25 + .../go/codec/goversion_maprange_gte_go112.go | 41 + .../go/codec/goversion_maprange_lt_go112.go | 45 + ...version_unexportedembeddedptr_gte_go110.go | 9 + ...oversion_unexportedembeddedptr_lt_go110.go | 9 + .../go/codec/goversion_unsupported_lt_go14.go | 22 + .../go/codec/goversion_vendor_eq_go15.go | 11 + .../go/codec/goversion_vendor_eq_go16.go | 11 + .../go/codec/goversion_vendor_gte_go17.go | 9 + .../go/codec/goversion_vendor_lt_go15.go | 9 + .../github.com/ugorji/go/codec/helper.go | 3021 +++ .../github.com/ugorji/go/codec/helper.s | 0 .../ugorji/go/codec/helper_internal.go | 147 + .../ugorji/go/codec/helper_not_unsafe.go | 706 + .../go/codec/helper_not_unsafe_not_gc.go | 21 + .../ugorji/go/codec/helper_unsafe.go | 1350 ++ .../go/codec/helper_unsafe_compiler_gc.go | 169 + .../go/codec/helper_unsafe_compiler_not_gc.go | 80 + .../vendor/github.com/ugorji/go/codec/json.go | 1460 ++ .../ugorji/go/codec/mammoth-test.go.tmpl | 235 + .../ugorji/go/codec/mammoth2-test.go.tmpl | 101 + .../github.com/ugorji/go/codec/msgpack.go | 1237 ++ .../github.com/ugorji/go/codec/reader.go | 607 + .../ugorji/go/codec/register_ext.go | 38 + ihub/vendor/github.com/ugorji/go/codec/rpc.go | 234 + .../github.com/ugorji/go/codec/simple.go | 750 + .../ugorji/go/codec/sort-slice.generated.go | 148 + .../ugorji/go/codec/sort-slice.go.tmpl | 68 + .../ugorji/go/codec/test-cbor-goldens.json | 639 + .../vendor/github.com/ugorji/go/codec/test.py | 138 + .../github.com/ugorji/go/codec/writer.go | 324 + ihub/vendor/github.com/upper/db/v4/.gitignore | 4 + ihub/vendor/github.com/upper/db/v4/LICENSE | 20 + ihub/vendor/github.com/upper/db/v4/Makefile | 42 + ihub/vendor/github.com/upper/db/v4/README.md | 37 + ihub/vendor/github.com/upper/db/v4/adapter.go | 75 + .../upper/db/v4/adapter/mysql/Makefile | 43 + .../upper/db/v4/adapter/mysql/README.md | 5 + .../upper/db/v4/adapter/mysql/collection.go | 77 + .../upper/db/v4/adapter/mysql/connection.go | 265 + .../upper/db/v4/adapter/mysql/custom_types.go | 172 + .../upper/db/v4/adapter/mysql/database.go | 189 + .../db/v4/adapter/mysql/docker-compose.yml | 14 + .../upper/db/v4/adapter/mysql/mysql.go | 51 + .../upper/db/v4/adapter/mysql/template.go | 219 + ihub/vendor/github.com/upper/db/v4/clauses.go | 489 + .../github.com/upper/db/v4/collection.go | 66 + .../github.com/upper/db/v4/comparison.go | 179 + ihub/vendor/github.com/upper/db/v4/cond.go | 130 + .../github.com/upper/db/v4/connection_url.go | 29 + ihub/vendor/github.com/upper/db/v4/db.go | 71 + ihub/vendor/github.com/upper/db/v4/errors.go | 63 + .../vendor/github.com/upper/db/v4/function.go | 48 + .../db/v4/internal/adapter/comparison.go | 60 + .../db/v4/internal/adapter/constraint.go | 72 + .../upper/db/v4/internal/adapter/func.go | 39 + .../db/v4/internal/adapter/logical_expr.go | 123 + .../upper/db/v4/internal/adapter/raw.go | 70 + .../upper/db/v4/internal/cache/cache.go | 134 + .../upper/db/v4/internal/cache/hash.go | 109 + .../upper/db/v4/internal/cache/interface.go | 34 + .../db/v4/internal/immutable/immutable.go | 28 + .../upper/db/v4/internal/reflectx/LICENSE | 23 + .../upper/db/v4/internal/reflectx/README.md | 17 + .../upper/db/v4/internal/reflectx/reflect.go | 405 + .../db/v4/internal/sqladapter/collection.go | 369 + .../db/v4/internal/sqladapter/compat/query.go | 72 + .../internal/sqladapter/compat/query_go18.go | 72 + .../db/v4/internal/sqladapter/exql/column.go | 83 + .../internal/sqladapter/exql/column_value.go | 111 + .../db/v4/internal/sqladapter/exql/columns.go | 83 + .../v4/internal/sqladapter/exql/database.go | 37 + .../db/v4/internal/sqladapter/exql/default.go | 192 + .../db/v4/internal/sqladapter/exql/errors.go | 5 + .../v4/internal/sqladapter/exql/group_by.go | 60 + .../v4/internal/sqladapter/exql/interfaces.go | 20 + .../db/v4/internal/sqladapter/exql/join.go | 195 + .../v4/internal/sqladapter/exql/order_by.go | 175 + .../db/v4/internal/sqladapter/exql/raw.go | 48 + .../v4/internal/sqladapter/exql/returning.go | 41 + .../v4/internal/sqladapter/exql/statement.go | 132 + .../db/v4/internal/sqladapter/exql/table.go | 98 + .../v4/internal/sqladapter/exql/template.go | 148 + .../db/v4/internal/sqladapter/exql/types.go | 35 + .../v4/internal/sqladapter/exql/utilities.go | 151 + .../db/v4/internal/sqladapter/exql/value.go | 166 + .../db/v4/internal/sqladapter/exql/where.go | 149 + .../upper/db/v4/internal/sqladapter/hash.go | 8 + .../upper/db/v4/internal/sqladapter/record.go | 122 + .../upper/db/v4/internal/sqladapter/result.go | 519 + .../db/v4/internal/sqladapter/session.go | 1106 + .../db/v4/internal/sqladapter/sqladapter.go | 83 + .../db/v4/internal/sqladapter/statement.go | 85 + .../upper/db/v4/internal/sqlbuilder/batch.go | 86 + .../db/v4/internal/sqlbuilder/builder.go | 632 + .../db/v4/internal/sqlbuilder/comparison.go | 122 + .../db/v4/internal/sqlbuilder/convert.go | 166 + .../db/v4/internal/sqlbuilder/custom_types.go | 11 + .../upper/db/v4/internal/sqlbuilder/delete.go | 195 + .../upper/db/v4/internal/sqlbuilder/errors.go | 14 + .../upper/db/v4/internal/sqlbuilder/fetch.go | 254 + .../upper/db/v4/internal/sqlbuilder/insert.go | 285 + .../db/v4/internal/sqlbuilder/paginate.go | 340 + .../db/v4/internal/sqlbuilder/scanner.go | 38 + .../upper/db/v4/internal/sqlbuilder/select.go | 524 + .../db/v4/internal/sqlbuilder/sqlbuilder.go | 40 + .../db/v4/internal/sqlbuilder/template.go | 323 + .../upper/db/v4/internal/sqlbuilder/update.go | 242 + .../db/v4/internal/sqlbuilder/wrapper.go | 85 + .../github.com/upper/db/v4/intersection.go | 73 + .../vendor/github.com/upper/db/v4/iterator.go | 47 + ihub/vendor/github.com/upper/db/v4/logger.go | 370 + ihub/vendor/github.com/upper/db/v4/marshal.go | 37 + ihub/vendor/github.com/upper/db/v4/raw.go | 40 + ihub/vendor/github.com/upper/db/v4/record.go | 82 + ihub/vendor/github.com/upper/db/v4/result.go | 214 + ihub/vendor/github.com/upper/db/v4/session.go | 99 + .../vendor/github.com/upper/db/v4/settings.go | 200 + ihub/vendor/github.com/upper/db/v4/sql.go | 212 + ihub/vendor/github.com/upper/db/v4/store.go | 57 + ihub/vendor/github.com/upper/db/v4/union.go | 64 + ihub/vendor/golang.org/x/arch/AUTHORS | 3 + ihub/vendor/golang.org/x/arch/CONTRIBUTORS | 3 + ihub/vendor/golang.org/x/arch/LICENSE | 27 + ihub/vendor/golang.org/x/arch/PATENTS | 22 + .../golang.org/x/arch/x86/x86asm/Makefile | 3 + .../golang.org/x/arch/x86/x86asm/decode.go | 1724 ++ .../golang.org/x/arch/x86/x86asm/gnu.go | 956 + .../golang.org/x/arch/x86/x86asm/inst.go | 649 + .../golang.org/x/arch/x86/x86asm/intel.go | 560 + .../golang.org/x/arch/x86/x86asm/plan9x.go | 382 + .../golang.org/x/arch/x86/x86asm/tables.go | 9925 +++++++++ ihub/vendor/golang.org/x/crypto/LICENSE | 27 + ihub/vendor/golang.org/x/crypto/PATENTS | 22 + .../x/crypto/ripemd160/ripemd160.go | 124 + .../x/crypto/ripemd160/ripemd160block.go | 165 + ihub/vendor/golang.org/x/crypto/sha3/doc.go | 62 + .../vendor/golang.org/x/crypto/sha3/hashes.go | 97 + .../x/crypto/sha3/hashes_generic.go | 28 + .../golang.org/x/crypto/sha3/keccakf.go | 415 + .../golang.org/x/crypto/sha3/keccakf_amd64.go | 14 + .../golang.org/x/crypto/sha3/keccakf_amd64.s | 391 + .../golang.org/x/crypto/sha3/register.go | 19 + ihub/vendor/golang.org/x/crypto/sha3/sha3.go | 193 + .../golang.org/x/crypto/sha3/sha3_s390x.go | 287 + .../golang.org/x/crypto/sha3/sha3_s390x.s | 34 + ihub/vendor/golang.org/x/crypto/sha3/shake.go | 173 + .../golang.org/x/crypto/sha3/shake_generic.go | 20 + ihub/vendor/golang.org/x/crypto/sha3/xor.go | 24 + .../golang.org/x/crypto/sha3/xor_generic.go | 28 + .../golang.org/x/crypto/sha3/xor_unaligned.go | 68 + ihub/vendor/golang.org/x/net/LICENSE | 27 + ihub/vendor/golang.org/x/net/PATENTS | 22 + .../golang.org/x/net/http/httpguts/guts.go | 50 + .../golang.org/x/net/http/httpguts/httplex.go | 352 + ihub/vendor/golang.org/x/net/http2/.gitignore | 2 + ihub/vendor/golang.org/x/net/http2/Dockerfile | 51 + ihub/vendor/golang.org/x/net/http2/Makefile | 3 + ihub/vendor/golang.org/x/net/http2/ascii.go | 53 + ihub/vendor/golang.org/x/net/http2/ciphers.go | 641 + .../x/net/http2/client_conn_pool.go | 311 + .../golang.org/x/net/http2/databuffer.go | 146 + ihub/vendor/golang.org/x/net/http2/errors.go | 145 + ihub/vendor/golang.org/x/net/http2/flow.go | 120 + ihub/vendor/golang.org/x/net/http2/frame.go | 1658 ++ ihub/vendor/golang.org/x/net/http2/go111.go | 30 + ihub/vendor/golang.org/x/net/http2/go115.go | 27 + ihub/vendor/golang.org/x/net/http2/go118.go | 17 + ihub/vendor/golang.org/x/net/http2/gotrack.go | 170 + ihub/vendor/golang.org/x/net/http2/h2c/h2c.go | 240 + .../golang.org/x/net/http2/headermap.go | 105 + .../golang.org/x/net/http2/hpack/encode.go | 245 + .../golang.org/x/net/http2/hpack/hpack.go | 523 + .../golang.org/x/net/http2/hpack/huffman.go | 226 + .../x/net/http2/hpack/static_table.go | 188 + .../golang.org/x/net/http2/hpack/tables.go | 403 + ihub/vendor/golang.org/x/net/http2/http2.go | 385 + .../golang.org/x/net/http2/not_go111.go | 21 + .../golang.org/x/net/http2/not_go115.go | 31 + .../golang.org/x/net/http2/not_go118.go | 17 + ihub/vendor/golang.org/x/net/http2/pipe.go | 179 + ihub/vendor/golang.org/x/net/http2/server.go | 3238 +++ .../golang.org/x/net/http2/transport.go | 3152 +++ ihub/vendor/golang.org/x/net/http2/write.go | 370 + .../golang.org/x/net/http2/writesched.go | 250 + .../x/net/http2/writesched_priority.go | 451 + .../x/net/http2/writesched_random.go | 77 + ihub/vendor/golang.org/x/net/idna/go118.go | 14 + .../golang.org/x/net/idna/idna10.0.0.go | 770 + .../vendor/golang.org/x/net/idna/idna9.0.0.go | 718 + .../vendor/golang.org/x/net/idna/pre_go118.go | 12 + ihub/vendor/golang.org/x/net/idna/punycode.go | 217 + .../golang.org/x/net/idna/tables10.0.0.go | 4560 +++++ .../golang.org/x/net/idna/tables11.0.0.go | 4654 +++++ .../golang.org/x/net/idna/tables12.0.0.go | 4734 +++++ .../golang.org/x/net/idna/tables13.0.0.go | 4840 +++++ .../golang.org/x/net/idna/tables9.0.0.go | 4487 +++++ ihub/vendor/golang.org/x/net/idna/trie.go | 72 + ihub/vendor/golang.org/x/net/idna/trieval.go | 119 + ihub/vendor/golang.org/x/sys/LICENSE | 27 + ihub/vendor/golang.org/x/sys/PATENTS | 22 + .../golang.org/x/sys/cpu/asm_aix_ppc64.s | 18 + ihub/vendor/golang.org/x/sys/cpu/byteorder.go | 66 + ihub/vendor/golang.org/x/sys/cpu/cpu.go | 287 + ihub/vendor/golang.org/x/sys/cpu/cpu_aix.go | 34 + ihub/vendor/golang.org/x/sys/cpu/cpu_arm.go | 73 + ihub/vendor/golang.org/x/sys/cpu/cpu_arm64.go | 172 + ihub/vendor/golang.org/x/sys/cpu/cpu_arm64.s | 32 + .../golang.org/x/sys/cpu/cpu_gc_arm64.go | 12 + .../golang.org/x/sys/cpu/cpu_gc_s390x.go | 22 + .../vendor/golang.org/x/sys/cpu/cpu_gc_x86.go | 17 + .../golang.org/x/sys/cpu/cpu_gccgo_arm64.go | 12 + .../golang.org/x/sys/cpu/cpu_gccgo_s390x.go | 23 + .../golang.org/x/sys/cpu/cpu_gccgo_x86.c | 39 + .../golang.org/x/sys/cpu/cpu_gccgo_x86.go | 33 + ihub/vendor/golang.org/x/sys/cpu/cpu_linux.go | 16 + .../golang.org/x/sys/cpu/cpu_linux_arm.go | 39 + .../golang.org/x/sys/cpu/cpu_linux_arm64.go | 111 + .../golang.org/x/sys/cpu/cpu_linux_mips64x.go | 24 + .../golang.org/x/sys/cpu/cpu_linux_noinit.go | 10 + .../golang.org/x/sys/cpu/cpu_linux_ppc64x.go | 32 + .../golang.org/x/sys/cpu/cpu_linux_s390x.go | 40 + .../golang.org/x/sys/cpu/cpu_loong64.go | 13 + .../golang.org/x/sys/cpu/cpu_mips64x.go | 16 + ihub/vendor/golang.org/x/sys/cpu/cpu_mipsx.go | 12 + .../golang.org/x/sys/cpu/cpu_netbsd_arm64.go | 173 + .../golang.org/x/sys/cpu/cpu_openbsd_arm64.go | 65 + .../golang.org/x/sys/cpu/cpu_openbsd_arm64.s | 11 + .../golang.org/x/sys/cpu/cpu_other_arm.go | 10 + .../golang.org/x/sys/cpu/cpu_other_arm64.go | 10 + .../golang.org/x/sys/cpu/cpu_other_mips64x.go | 13 + .../golang.org/x/sys/cpu/cpu_other_ppc64x.go | 15 + .../golang.org/x/sys/cpu/cpu_other_riscv64.go | 12 + .../vendor/golang.org/x/sys/cpu/cpu_ppc64x.go | 17 + .../golang.org/x/sys/cpu/cpu_riscv64.go | 12 + ihub/vendor/golang.org/x/sys/cpu/cpu_s390x.go | 172 + ihub/vendor/golang.org/x/sys/cpu/cpu_s390x.s | 58 + ihub/vendor/golang.org/x/sys/cpu/cpu_wasm.go | 18 + ihub/vendor/golang.org/x/sys/cpu/cpu_x86.go | 145 + ihub/vendor/golang.org/x/sys/cpu/cpu_x86.s | 28 + ihub/vendor/golang.org/x/sys/cpu/cpu_zos.go | 10 + .../golang.org/x/sys/cpu/cpu_zos_s390x.go | 25 + .../vendor/golang.org/x/sys/cpu/endian_big.go | 11 + .../golang.org/x/sys/cpu/endian_little.go | 11 + .../golang.org/x/sys/cpu/hwcap_linux.go | 56 + ihub/vendor/golang.org/x/sys/cpu/parse.go | 43 + .../x/sys/cpu/proc_cpuinfo_linux.go | 54 + .../golang.org/x/sys/cpu/syscall_aix_gccgo.go | 27 + .../x/sys/cpu/syscall_aix_ppc64_gc.go | 36 + .../sys/internal/unsafeheader/unsafeheader.go | 30 + ihub/vendor/golang.org/x/sys/unix/.gitignore | 2 + ihub/vendor/golang.org/x/sys/unix/README.md | 184 + .../golang.org/x/sys/unix/affinity_linux.go | 86 + ihub/vendor/golang.org/x/sys/unix/aliases.go | 15 + .../golang.org/x/sys/unix/asm_aix_ppc64.s | 18 + .../golang.org/x/sys/unix/asm_bsd_386.s | 29 + .../golang.org/x/sys/unix/asm_bsd_amd64.s | 29 + .../golang.org/x/sys/unix/asm_bsd_arm.s | 29 + .../golang.org/x/sys/unix/asm_bsd_arm64.s | 29 + .../golang.org/x/sys/unix/asm_bsd_ppc64.s | 31 + .../golang.org/x/sys/unix/asm_bsd_riscv64.s | 29 + .../golang.org/x/sys/unix/asm_linux_386.s | 66 + .../golang.org/x/sys/unix/asm_linux_amd64.s | 58 + .../golang.org/x/sys/unix/asm_linux_arm.s | 57 + .../golang.org/x/sys/unix/asm_linux_arm64.s | 53 + .../golang.org/x/sys/unix/asm_linux_loong64.s | 54 + .../golang.org/x/sys/unix/asm_linux_mips64x.s | 57 + .../golang.org/x/sys/unix/asm_linux_mipsx.s | 55 + .../golang.org/x/sys/unix/asm_linux_ppc64x.s | 45 + .../golang.org/x/sys/unix/asm_linux_riscv64.s | 49 + .../golang.org/x/sys/unix/asm_linux_s390x.s | 57 + .../x/sys/unix/asm_openbsd_mips64.s | 30 + .../golang.org/x/sys/unix/asm_solaris_amd64.s | 18 + .../golang.org/x/sys/unix/asm_zos_s390x.s | 426 + .../golang.org/x/sys/unix/bluetooth_linux.go | 36 + .../golang.org/x/sys/unix/cap_freebsd.go | 196 + .../vendor/golang.org/x/sys/unix/constants.go | 14 + .../golang.org/x/sys/unix/dev_aix_ppc.go | 27 + .../golang.org/x/sys/unix/dev_aix_ppc64.go | 29 + .../golang.org/x/sys/unix/dev_darwin.go | 24 + .../golang.org/x/sys/unix/dev_dragonfly.go | 30 + .../golang.org/x/sys/unix/dev_freebsd.go | 30 + .../vendor/golang.org/x/sys/unix/dev_linux.go | 42 + .../golang.org/x/sys/unix/dev_netbsd.go | 29 + .../golang.org/x/sys/unix/dev_openbsd.go | 29 + ihub/vendor/golang.org/x/sys/unix/dev_zos.go | 29 + ihub/vendor/golang.org/x/sys/unix/dirent.go | 103 + .../golang.org/x/sys/unix/endian_big.go | 10 + .../golang.org/x/sys/unix/endian_little.go | 10 + ihub/vendor/golang.org/x/sys/unix/env_unix.go | 32 + .../vendor/golang.org/x/sys/unix/epoll_zos.go | 221 + ihub/vendor/golang.org/x/sys/unix/fcntl.go | 37 + .../golang.org/x/sys/unix/fcntl_darwin.go | 24 + .../x/sys/unix/fcntl_linux_32bit.go | 14 + ihub/vendor/golang.org/x/sys/unix/fdset.go | 30 + .../golang.org/x/sys/unix/fstatfs_zos.go | 164 + ihub/vendor/golang.org/x/sys/unix/gccgo.go | 60 + ihub/vendor/golang.org/x/sys/unix/gccgo_c.c | 45 + .../x/sys/unix/gccgo_linux_amd64.go | 21 + .../golang.org/x/sys/unix/ifreq_linux.go | 142 + ihub/vendor/golang.org/x/sys/unix/ioctl.go | 75 + .../golang.org/x/sys/unix/ioctl_linux.go | 233 + .../vendor/golang.org/x/sys/unix/ioctl_zos.go | 74 + ihub/vendor/golang.org/x/sys/unix/mkall.sh | 249 + ihub/vendor/golang.org/x/sys/unix/mkerrors.sh | 778 + .../golang.org/x/sys/unix/pagesize_unix.go | 16 + .../golang.org/x/sys/unix/pledge_openbsd.go | 163 + .../golang.org/x/sys/unix/ptrace_darwin.go | 12 + .../golang.org/x/sys/unix/ptrace_ios.go | 12 + ihub/vendor/golang.org/x/sys/unix/race.go | 31 + ihub/vendor/golang.org/x/sys/unix/race0.go | 26 + .../x/sys/unix/readdirent_getdents.go | 13 + .../x/sys/unix/readdirent_getdirentries.go | 20 + .../x/sys/unix/sockcmsg_dragonfly.go | 16 + .../golang.org/x/sys/unix/sockcmsg_linux.go | 85 + .../golang.org/x/sys/unix/sockcmsg_unix.go | 107 + .../x/sys/unix/sockcmsg_unix_other.go | 47 + ihub/vendor/golang.org/x/sys/unix/syscall.go | 87 + .../golang.org/x/sys/unix/syscall_aix.go | 600 + .../golang.org/x/sys/unix/syscall_aix_ppc.go | 54 + .../x/sys/unix/syscall_aix_ppc64.go | 85 + .../golang.org/x/sys/unix/syscall_bsd.go | 625 + .../golang.org/x/sys/unix/syscall_darwin.go | 831 + .../x/sys/unix/syscall_darwin_amd64.go | 51 + .../x/sys/unix/syscall_darwin_arm64.go | 51 + .../x/sys/unix/syscall_darwin_libSystem.go | 27 + .../x/sys/unix/syscall_dragonfly.go | 545 + .../x/sys/unix/syscall_dragonfly_amd64.go | 57 + .../golang.org/x/sys/unix/syscall_freebsd.go | 615 + .../x/sys/unix/syscall_freebsd_386.go | 72 + .../x/sys/unix/syscall_freebsd_amd64.go | 72 + .../x/sys/unix/syscall_freebsd_arm.go | 68 + .../x/sys/unix/syscall_freebsd_arm64.go | 68 + .../x/sys/unix/syscall_freebsd_riscv64.go | 68 + .../golang.org/x/sys/unix/syscall_hurd.go | 22 + .../golang.org/x/sys/unix/syscall_hurd_386.go | 29 + .../golang.org/x/sys/unix/syscall_illumos.go | 79 + .../golang.org/x/sys/unix/syscall_linux.go | 2492 +++ .../x/sys/unix/syscall_linux_386.go | 342 + .../x/sys/unix/syscall_linux_alarm.go | 14 + .../x/sys/unix/syscall_linux_amd64.go | 147 + .../x/sys/unix/syscall_linux_amd64_gc.go | 13 + .../x/sys/unix/syscall_linux_arm.go | 244 + .../x/sys/unix/syscall_linux_arm64.go | 195 + .../golang.org/x/sys/unix/syscall_linux_gc.go | 15 + .../x/sys/unix/syscall_linux_gc_386.go | 17 + .../x/sys/unix/syscall_linux_gc_arm.go | 14 + .../x/sys/unix/syscall_linux_gccgo_386.go | 31 + .../x/sys/unix/syscall_linux_gccgo_arm.go | 21 + .../x/sys/unix/syscall_linux_loong64.go | 222 + .../x/sys/unix/syscall_linux_mips64x.go | 191 + .../x/sys/unix/syscall_linux_mipsx.go | 203 + .../x/sys/unix/syscall_linux_ppc.go | 232 + .../x/sys/unix/syscall_linux_ppc64x.go | 118 + .../x/sys/unix/syscall_linux_riscv64.go | 180 + .../x/sys/unix/syscall_linux_s390x.go | 298 + .../x/sys/unix/syscall_linux_sparc64.go | 114 + .../golang.org/x/sys/unix/syscall_netbsd.go | 624 + .../x/sys/unix/syscall_netbsd_386.go | 38 + .../x/sys/unix/syscall_netbsd_amd64.go | 38 + .../x/sys/unix/syscall_netbsd_arm.go | 38 + .../x/sys/unix/syscall_netbsd_arm64.go | 38 + .../golang.org/x/sys/unix/syscall_openbsd.go | 390 + .../x/sys/unix/syscall_openbsd_386.go | 42 + .../x/sys/unix/syscall_openbsd_amd64.go | 42 + .../x/sys/unix/syscall_openbsd_arm.go | 42 + .../x/sys/unix/syscall_openbsd_arm64.go | 42 + .../x/sys/unix/syscall_openbsd_libc.go | 27 + .../x/sys/unix/syscall_openbsd_mips64.go | 39 + .../x/sys/unix/syscall_openbsd_ppc64.go | 42 + .../x/sys/unix/syscall_openbsd_riscv64.go | 42 + .../golang.org/x/sys/unix/syscall_solaris.go | 1133 ++ .../x/sys/unix/syscall_solaris_amd64.go | 28 + .../golang.org/x/sys/unix/syscall_unix.go | 589 + .../golang.org/x/sys/unix/syscall_unix_gc.go | 16 + .../x/sys/unix/syscall_unix_gc_ppc64x.go | 25 + .../x/sys/unix/syscall_zos_s390x.go | 1994 ++ .../golang.org/x/sys/unix/sysvshm_linux.go | 21 + .../golang.org/x/sys/unix/sysvshm_unix.go | 52 + .../x/sys/unix/sysvshm_unix_other.go | 14 + .../golang.org/x/sys/unix/timestruct.go | 77 + .../golang.org/x/sys/unix/unveil_openbsd.go | 42 + .../vendor/golang.org/x/sys/unix/xattr_bsd.go | 281 + .../golang.org/x/sys/unix/zerrors_aix_ppc.go | 1385 ++ .../x/sys/unix/zerrors_aix_ppc64.go | 1386 ++ .../x/sys/unix/zerrors_darwin_amd64.go | 1892 ++ .../x/sys/unix/zerrors_darwin_arm64.go | 1892 ++ .../x/sys/unix/zerrors_dragonfly_amd64.go | 1738 ++ .../x/sys/unix/zerrors_freebsd_386.go | 2043 ++ .../x/sys/unix/zerrors_freebsd_amd64.go | 2040 ++ .../x/sys/unix/zerrors_freebsd_arm.go | 2034 ++ .../x/sys/unix/zerrors_freebsd_arm64.go | 2034 ++ .../x/sys/unix/zerrors_freebsd_riscv64.go | 2148 ++ .../golang.org/x/sys/unix/zerrors_linux.go | 3473 ++++ .../x/sys/unix/zerrors_linux_386.go | 829 + .../x/sys/unix/zerrors_linux_amd64.go | 829 + .../x/sys/unix/zerrors_linux_arm.go | 835 + .../x/sys/unix/zerrors_linux_arm64.go | 827 + .../x/sys/unix/zerrors_linux_loong64.go | 819 + .../x/sys/unix/zerrors_linux_mips.go | 836 + .../x/sys/unix/zerrors_linux_mips64.go | 836 + .../x/sys/unix/zerrors_linux_mips64le.go | 836 + .../x/sys/unix/zerrors_linux_mipsle.go | 836 + .../x/sys/unix/zerrors_linux_ppc.go | 888 + .../x/sys/unix/zerrors_linux_ppc64.go | 892 + .../x/sys/unix/zerrors_linux_ppc64le.go | 892 + .../x/sys/unix/zerrors_linux_riscv64.go | 816 + .../x/sys/unix/zerrors_linux_s390x.go | 891 + .../x/sys/unix/zerrors_linux_sparc64.go | 886 + .../x/sys/unix/zerrors_netbsd_386.go | 1780 ++ .../x/sys/unix/zerrors_netbsd_amd64.go | 1770 ++ .../x/sys/unix/zerrors_netbsd_arm.go | 1759 ++ .../x/sys/unix/zerrors_netbsd_arm64.go | 1770 ++ .../x/sys/unix/zerrors_openbsd_386.go | 1906 ++ .../x/sys/unix/zerrors_openbsd_amd64.go | 1906 ++ .../x/sys/unix/zerrors_openbsd_arm.go | 1906 ++ .../x/sys/unix/zerrors_openbsd_arm64.go | 1906 ++ .../x/sys/unix/zerrors_openbsd_mips64.go | 1906 ++ .../x/sys/unix/zerrors_openbsd_ppc64.go | 1905 ++ .../x/sys/unix/zerrors_openbsd_riscv64.go | 1904 ++ .../x/sys/unix/zerrors_solaris_amd64.go | 1557 ++ .../x/sys/unix/zerrors_zos_s390x.go | 860 + .../x/sys/unix/zptrace_armnn_linux.go | 42 + .../x/sys/unix/zptrace_linux_arm64.go | 17 + .../x/sys/unix/zptrace_mipsnn_linux.go | 51 + .../x/sys/unix/zptrace_mipsnnle_linux.go | 51 + .../x/sys/unix/zptrace_x86_linux.go | 81 + .../golang.org/x/sys/unix/zsyscall_aix_ppc.go | 1485 ++ .../x/sys/unix/zsyscall_aix_ppc64.go | 1443 ++ .../x/sys/unix/zsyscall_aix_ppc64_gc.go | 1192 ++ .../x/sys/unix/zsyscall_aix_ppc64_gccgo.go | 1070 + .../x/sys/unix/zsyscall_darwin_amd64.go | 2545 +++ .../x/sys/unix/zsyscall_darwin_amd64.s | 904 + .../x/sys/unix/zsyscall_darwin_arm64.go | 2545 +++ .../x/sys/unix/zsyscall_darwin_arm64.s | 904 + .../x/sys/unix/zsyscall_dragonfly_amd64.go | 1689 ++ .../x/sys/unix/zsyscall_freebsd_386.go | 1899 ++ .../x/sys/unix/zsyscall_freebsd_amd64.go | 1899 ++ .../x/sys/unix/zsyscall_freebsd_arm.go | 1899 ++ .../x/sys/unix/zsyscall_freebsd_arm64.go | 1899 ++ .../x/sys/unix/zsyscall_freebsd_riscv64.go | 1899 ++ .../x/sys/unix/zsyscall_illumos_amd64.go | 102 + .../golang.org/x/sys/unix/zsyscall_linux.go | 2174 ++ .../x/sys/unix/zsyscall_linux_386.go | 497 + .../x/sys/unix/zsyscall_linux_amd64.go | 664 + .../x/sys/unix/zsyscall_linux_arm.go | 612 + .../x/sys/unix/zsyscall_linux_arm64.go | 563 + .../x/sys/unix/zsyscall_linux_loong64.go | 487 + .../x/sys/unix/zsyscall_linux_mips.go | 664 + .../x/sys/unix/zsyscall_linux_mips64.go | 658 + .../x/sys/unix/zsyscall_linux_mips64le.go | 647 + .../x/sys/unix/zsyscall_linux_mipsle.go | 664 + .../x/sys/unix/zsyscall_linux_ppc.go | 669 + .../x/sys/unix/zsyscall_linux_ppc64.go | 715 + .../x/sys/unix/zsyscall_linux_ppc64le.go | 715 + .../x/sys/unix/zsyscall_linux_riscv64.go | 543 + .../x/sys/unix/zsyscall_linux_s390x.go | 506 + .../x/sys/unix/zsyscall_linux_sparc64.go | 659 + .../x/sys/unix/zsyscall_netbsd_386.go | 1860 ++ .../x/sys/unix/zsyscall_netbsd_amd64.go | 1860 ++ .../x/sys/unix/zsyscall_netbsd_arm.go | 1860 ++ .../x/sys/unix/zsyscall_netbsd_arm64.go | 1860 ++ .../x/sys/unix/zsyscall_openbsd_386.go | 2235 +++ .../x/sys/unix/zsyscall_openbsd_386.s | 669 + .../x/sys/unix/zsyscall_openbsd_amd64.go | 2235 +++ .../x/sys/unix/zsyscall_openbsd_amd64.s | 669 + .../x/sys/unix/zsyscall_openbsd_arm.go | 2235 +++ .../x/sys/unix/zsyscall_openbsd_arm.s | 669 + .../x/sys/unix/zsyscall_openbsd_arm64.go | 2235 +++ .../x/sys/unix/zsyscall_openbsd_arm64.s | 669 + .../x/sys/unix/zsyscall_openbsd_mips64.go | 2235 +++ .../x/sys/unix/zsyscall_openbsd_mips64.s | 669 + .../x/sys/unix/zsyscall_openbsd_ppc64.go | 2235 +++ .../x/sys/unix/zsyscall_openbsd_ppc64.s | 802 + .../x/sys/unix/zsyscall_openbsd_riscv64.go | 2235 +++ .../x/sys/unix/zsyscall_openbsd_riscv64.s | 669 + .../x/sys/unix/zsyscall_solaris_amd64.go | 2106 ++ .../x/sys/unix/zsyscall_zos_s390x.go | 1255 ++ .../x/sys/unix/zsysctl_openbsd_386.go | 281 + .../x/sys/unix/zsysctl_openbsd_amd64.go | 281 + .../x/sys/unix/zsysctl_openbsd_arm.go | 281 + .../x/sys/unix/zsysctl_openbsd_arm64.go | 281 + .../x/sys/unix/zsysctl_openbsd_mips64.go | 281 + .../x/sys/unix/zsysctl_openbsd_ppc64.go | 281 + .../x/sys/unix/zsysctl_openbsd_riscv64.go | 282 + .../x/sys/unix/zsysnum_darwin_amd64.go | 440 + .../x/sys/unix/zsysnum_darwin_arm64.go | 438 + .../x/sys/unix/zsysnum_dragonfly_amd64.go | 317 + .../x/sys/unix/zsysnum_freebsd_386.go | 394 + .../x/sys/unix/zsysnum_freebsd_amd64.go | 394 + .../x/sys/unix/zsysnum_freebsd_arm.go | 394 + .../x/sys/unix/zsysnum_freebsd_arm64.go | 394 + .../x/sys/unix/zsysnum_freebsd_riscv64.go | 394 + .../x/sys/unix/zsysnum_linux_386.go | 450 + .../x/sys/unix/zsysnum_linux_amd64.go | 372 + .../x/sys/unix/zsysnum_linux_arm.go | 414 + .../x/sys/unix/zsysnum_linux_arm64.go | 317 + .../x/sys/unix/zsysnum_linux_loong64.go | 311 + .../x/sys/unix/zsysnum_linux_mips.go | 434 + .../x/sys/unix/zsysnum_linux_mips64.go | 364 + .../x/sys/unix/zsysnum_linux_mips64le.go | 364 + .../x/sys/unix/zsysnum_linux_mipsle.go | 434 + .../x/sys/unix/zsysnum_linux_ppc.go | 441 + .../x/sys/unix/zsysnum_linux_ppc64.go | 413 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 413 + .../x/sys/unix/zsysnum_linux_riscv64.go | 316 + .../x/sys/unix/zsysnum_linux_s390x.go | 378 + .../x/sys/unix/zsysnum_linux_sparc64.go | 392 + .../x/sys/unix/zsysnum_netbsd_386.go | 275 + .../x/sys/unix/zsysnum_netbsd_amd64.go | 275 + .../x/sys/unix/zsysnum_netbsd_arm.go | 275 + .../x/sys/unix/zsysnum_netbsd_arm64.go | 275 + .../x/sys/unix/zsysnum_openbsd_386.go | 220 + .../x/sys/unix/zsysnum_openbsd_amd64.go | 220 + .../x/sys/unix/zsysnum_openbsd_arm.go | 220 + .../x/sys/unix/zsysnum_openbsd_arm64.go | 219 + .../x/sys/unix/zsysnum_openbsd_mips64.go | 222 + .../x/sys/unix/zsysnum_openbsd_ppc64.go | 218 + .../x/sys/unix/zsysnum_openbsd_riscv64.go | 219 + .../x/sys/unix/zsysnum_zos_s390x.go | 2670 +++ .../golang.org/x/sys/unix/ztypes_aix_ppc.go | 354 + .../golang.org/x/sys/unix/ztypes_aix_ppc64.go | 358 + .../x/sys/unix/ztypes_darwin_amd64.go | 795 + .../x/sys/unix/ztypes_darwin_arm64.go | 795 + .../x/sys/unix/ztypes_dragonfly_amd64.go | 474 + .../x/sys/unix/ztypes_freebsd_386.go | 651 + .../x/sys/unix/ztypes_freebsd_amd64.go | 656 + .../x/sys/unix/ztypes_freebsd_arm.go | 642 + .../x/sys/unix/ztypes_freebsd_arm64.go | 636 + .../x/sys/unix/ztypes_freebsd_riscv64.go | 638 + .../golang.org/x/sys/unix/ztypes_linux.go | 5754 ++++++ .../golang.org/x/sys/unix/ztypes_linux_386.go | 696 + .../x/sys/unix/ztypes_linux_amd64.go | 711 + .../golang.org/x/sys/unix/ztypes_linux_arm.go | 691 + .../x/sys/unix/ztypes_linux_arm64.go | 690 + .../x/sys/unix/ztypes_linux_loong64.go | 691 + .../x/sys/unix/ztypes_linux_mips.go | 696 + .../x/sys/unix/ztypes_linux_mips64.go | 693 + .../x/sys/unix/ztypes_linux_mips64le.go | 693 + .../x/sys/unix/ztypes_linux_mipsle.go | 696 + .../golang.org/x/sys/unix/ztypes_linux_ppc.go | 704 + .../x/sys/unix/ztypes_linux_ppc64.go | 699 + .../x/sys/unix/ztypes_linux_ppc64le.go | 699 + .../x/sys/unix/ztypes_linux_riscv64.go | 718 + .../x/sys/unix/ztypes_linux_s390x.go | 713 + .../x/sys/unix/ztypes_linux_sparc64.go | 694 + .../x/sys/unix/ztypes_netbsd_386.go | 586 + .../x/sys/unix/ztypes_netbsd_amd64.go | 594 + .../x/sys/unix/ztypes_netbsd_arm.go | 591 + .../x/sys/unix/ztypes_netbsd_arm64.go | 594 + .../x/sys/unix/ztypes_openbsd_386.go | 569 + .../x/sys/unix/ztypes_openbsd_amd64.go | 569 + .../x/sys/unix/ztypes_openbsd_arm.go | 576 + .../x/sys/unix/ztypes_openbsd_arm64.go | 569 + .../x/sys/unix/ztypes_openbsd_mips64.go | 569 + .../x/sys/unix/ztypes_openbsd_ppc64.go | 571 + .../x/sys/unix/ztypes_openbsd_riscv64.go | 571 + .../x/sys/unix/ztypes_solaris_amd64.go | 517 + .../golang.org/x/sys/unix/ztypes_zos_s390x.go | 415 + .../golang.org/x/sys/windows/aliases.go | 13 + .../golang.org/x/sys/windows/dll_windows.go | 416 + ihub/vendor/golang.org/x/sys/windows/empty.s | 9 + .../golang.org/x/sys/windows/env_windows.go | 54 + .../golang.org/x/sys/windows/eventlog.go | 21 + .../golang.org/x/sys/windows/exec_windows.go | 178 + .../x/sys/windows/memory_windows.go | 48 + .../golang.org/x/sys/windows/mkerrors.bash | 70 + .../x/sys/windows/mkknownfolderids.bash | 27 + .../golang.org/x/sys/windows/mksyscall.go | 10 + ihub/vendor/golang.org/x/sys/windows/race.go | 31 + ihub/vendor/golang.org/x/sys/windows/race0.go | 26 + .../x/sys/windows/security_windows.go | 1444 ++ .../golang.org/x/sys/windows/service.go | 247 + .../x/sys/windows/setupapi_windows.go | 1425 ++ ihub/vendor/golang.org/x/sys/windows/str.go | 23 + .../golang.org/x/sys/windows/syscall.go | 105 + .../x/sys/windows/syscall_windows.go | 1806 ++ .../golang.org/x/sys/windows/types_windows.go | 3260 +++ .../x/sys/windows/types_windows_386.go | 35 + .../x/sys/windows/types_windows_amd64.go | 34 + .../x/sys/windows/types_windows_arm.go | 35 + .../x/sys/windows/types_windows_arm64.go | 34 + .../x/sys/windows/zerrors_windows.go | 9468 +++++++++ .../x/sys/windows/zknownfolderids_windows.go | 149 + .../x/sys/windows/zsyscall_windows.go | 4309 ++++ ihub/vendor/golang.org/x/text/LICENSE | 27 + ihub/vendor/golang.org/x/text/PATENTS | 22 + .../x/text/internal/language/common.go | 16 + .../x/text/internal/language/compact.go | 29 + .../text/internal/language/compact/compact.go | 61 + .../internal/language/compact/language.go | 260 + .../text/internal/language/compact/parents.go | 120 + .../text/internal/language/compact/tables.go | 1015 + .../x/text/internal/language/compact/tags.go | 91 + .../x/text/internal/language/compose.go | 167 + .../x/text/internal/language/coverage.go | 28 + .../x/text/internal/language/language.go | 627 + .../x/text/internal/language/lookup.go | 412 + .../x/text/internal/language/match.go | 226 + .../x/text/internal/language/parse.go | 608 + .../x/text/internal/language/tables.go | 3472 ++++ .../x/text/internal/language/tags.go | 48 + .../golang.org/x/text/internal/tag/tag.go | 100 + .../golang.org/x/text/language/coverage.go | 187 + ihub/vendor/golang.org/x/text/language/doc.go | 98 + .../golang.org/x/text/language/language.go | 605 + .../golang.org/x/text/language/match.go | 735 + .../golang.org/x/text/language/parse.go | 256 + .../golang.org/x/text/language/tables.go | 298 + .../vendor/golang.org/x/text/language/tags.go | 145 + ihub/vendor/golang.org/x/text/runes/cond.go | 187 + ihub/vendor/golang.org/x/text/runes/runes.go | 355 + .../x/text/secure/bidirule/bidirule.go | 336 + .../x/text/secure/bidirule/bidirule10.0.0.go | 12 + .../x/text/secure/bidirule/bidirule9.0.0.go | 15 + .../golang.org/x/text/transform/transform.go | 709 + .../golang.org/x/text/unicode/bidi/bidi.go | 359 + .../golang.org/x/text/unicode/bidi/bracket.go | 335 + .../golang.org/x/text/unicode/bidi/core.go | 1071 + .../golang.org/x/text/unicode/bidi/prop.go | 206 + .../x/text/unicode/bidi/tables10.0.0.go | 1816 ++ .../x/text/unicode/bidi/tables11.0.0.go | 1888 ++ .../x/text/unicode/bidi/tables12.0.0.go | 1924 ++ .../x/text/unicode/bidi/tables13.0.0.go | 1956 ++ .../x/text/unicode/bidi/tables9.0.0.go | 1782 ++ .../golang.org/x/text/unicode/bidi/trieval.go | 48 + .../x/text/unicode/norm/composition.go | 512 + .../x/text/unicode/norm/forminfo.go | 279 + .../golang.org/x/text/unicode/norm/input.go | 109 + .../golang.org/x/text/unicode/norm/iter.go | 458 + .../x/text/unicode/norm/normalize.go | 610 + .../x/text/unicode/norm/readwriter.go | 125 + .../x/text/unicode/norm/tables10.0.0.go | 7658 +++++++ .../x/text/unicode/norm/tables11.0.0.go | 7694 +++++++ .../x/text/unicode/norm/tables12.0.0.go | 7711 +++++++ .../x/text/unicode/norm/tables13.0.0.go | 7761 ++++++++ .../x/text/unicode/norm/tables9.0.0.go | 7638 +++++++ .../x/text/unicode/norm/transform.go | 88 + .../golang.org/x/text/unicode/norm/trie.go | 54 + .../vendor/google.golang.org/protobuf/LICENSE | 27 + .../vendor/google.golang.org/protobuf/PATENTS | 22 + .../protobuf/encoding/protowire/wire.go | 551 + .../protobuf/internal/detrand/rand.go | 69 + .../encoding/messageset/messageset.go | 242 + .../protobuf/internal/errors/errors.go | 89 + .../protobuf/internal/errors/is_go112.go | 40 + .../protobuf/internal/errors/is_go113.go | 13 + .../protobuf/internal/flags/flags.go | 24 + .../internal/flags/proto_legacy_disable.go | 10 + .../internal/flags/proto_legacy_enable.go | 10 + .../protobuf/internal/genid/any_gen.go | 34 + .../protobuf/internal/genid/api_gen.go | 106 + .../protobuf/internal/genid/descriptor_gen.go | 829 + .../protobuf/internal/genid/doc.go | 11 + .../protobuf/internal/genid/duration_gen.go | 34 + .../protobuf/internal/genid/empty_gen.go | 19 + .../protobuf/internal/genid/field_mask_gen.go | 31 + .../protobuf/internal/genid/goname.go | 25 + .../protobuf/internal/genid/map_entry.go | 16 + .../internal/genid/source_context_gen.go | 31 + .../protobuf/internal/genid/struct_gen.go | 116 + .../protobuf/internal/genid/timestamp_gen.go | 34 + .../protobuf/internal/genid/type_gen.go | 184 + .../protobuf/internal/genid/wrappers.go | 13 + .../protobuf/internal/genid/wrappers_gen.go | 175 + .../protobuf/internal/order/order.go | 89 + .../protobuf/internal/order/range.go | 115 + .../protobuf/internal/pragma/pragma.go | 29 + .../protobuf/internal/strs/strings.go | 196 + .../protobuf/internal/strs/strings_pure.go | 28 + .../protobuf/internal/strs/strings_unsafe.go | 95 + .../protobuf/proto/checkinit.go | 71 + .../protobuf/proto/decode.go | 294 + .../protobuf/proto/decode_gen.go | 603 + .../google.golang.org/protobuf/proto/doc.go | 89 + .../protobuf/proto/encode.go | 322 + .../protobuf/proto/encode_gen.go | 97 + .../google.golang.org/protobuf/proto/equal.go | 171 + .../protobuf/proto/extension.go | 92 + .../google.golang.org/protobuf/proto/merge.go | 139 + .../protobuf/proto/messageset.go | 93 + .../google.golang.org/protobuf/proto/proto.go | 43 + .../protobuf/proto/proto_methods.go | 20 + .../protobuf/proto/proto_reflect.go | 20 + .../google.golang.org/protobuf/proto/reset.go | 43 + .../google.golang.org/protobuf/proto/size.go | 97 + .../protobuf/proto/size_gen.go | 55 + .../protobuf/proto/wrappers.go | 29 + .../protobuf/reflect/protoreflect/methods.go | 78 + .../protobuf/reflect/protoreflect/proto.go | 508 + .../protobuf/reflect/protoreflect/source.go | 129 + .../reflect/protoreflect/source_gen.go | 461 + .../protobuf/reflect/protoreflect/type.go | 666 + .../protobuf/reflect/protoreflect/value.go | 285 + .../reflect/protoreflect/value_pure.go | 60 + .../reflect/protoreflect/value_union.go | 438 + .../reflect/protoreflect/value_unsafe.go | 99 + .../reflect/protoregistry/registry.go | 882 + .../protobuf/runtime/protoiface/legacy.go | 15 + .../protobuf/runtime/protoiface/methods.go | 168 + ihub/vendor/gopkg.in/ini.v1/.editorconfig | 12 + ihub/vendor/gopkg.in/ini.v1/.gitignore | 7 + ihub/vendor/gopkg.in/ini.v1/.golangci.yml | 27 + ihub/vendor/gopkg.in/ini.v1/LICENSE | 191 + ihub/vendor/gopkg.in/ini.v1/Makefile | 15 + ihub/vendor/gopkg.in/ini.v1/README.md | 43 + ihub/vendor/gopkg.in/ini.v1/codecov.yml | 16 + ihub/vendor/gopkg.in/ini.v1/data_source.go | 76 + ihub/vendor/gopkg.in/ini.v1/deprecated.go | 22 + ihub/vendor/gopkg.in/ini.v1/error.go | 49 + ihub/vendor/gopkg.in/ini.v1/file.go | 541 + ihub/vendor/gopkg.in/ini.v1/helper.go | 24 + ihub/vendor/gopkg.in/ini.v1/ini.go | 176 + ihub/vendor/gopkg.in/ini.v1/key.go | 837 + ihub/vendor/gopkg.in/ini.v1/parser.go | 520 + ihub/vendor/gopkg.in/ini.v1/section.go | 256 + ihub/vendor/gopkg.in/ini.v1/struct.go | 747 + ihub/vendor/gopkg.in/yaml.v3/LICENSE | 50 + ihub/vendor/gopkg.in/yaml.v3/NOTICE | 13 + ihub/vendor/gopkg.in/yaml.v3/README.md | 150 + ihub/vendor/gopkg.in/yaml.v3/apic.go | 747 + ihub/vendor/gopkg.in/yaml.v3/decode.go | 1000 + ihub/vendor/gopkg.in/yaml.v3/emitterc.go | 2020 ++ ihub/vendor/gopkg.in/yaml.v3/encode.go | 577 + ihub/vendor/gopkg.in/yaml.v3/parserc.go | 1258 ++ ihub/vendor/gopkg.in/yaml.v3/readerc.go | 434 + ihub/vendor/gopkg.in/yaml.v3/resolve.go | 326 + ihub/vendor/gopkg.in/yaml.v3/scannerc.go | 3038 +++ ihub/vendor/gopkg.in/yaml.v3/sorter.go | 134 + ihub/vendor/gopkg.in/yaml.v3/writerc.go | 48 + ihub/vendor/gopkg.in/yaml.v3/yaml.go | 698 + ihub/vendor/gopkg.in/yaml.v3/yamlh.go | 807 + ihub/vendor/gopkg.in/yaml.v3/yamlprivateh.go | 198 + ihub/vendor/modules.txt | 232 + 1642 files changed, 680079 insertions(+) create mode 100644 ihub/vendor/github.com/bytedance/sonic/.gitignore create mode 100644 ihub/vendor/github.com/bytedance/sonic/.gitmodules create mode 100644 ihub/vendor/github.com/bytedance/sonic/.licenserc.yaml create mode 100644 ihub/vendor/github.com/bytedance/sonic/CODE_OF_CONDUCT.md create mode 100644 ihub/vendor/github.com/bytedance/sonic/CONTRIBUTING.md create mode 100644 ihub/vendor/github.com/bytedance/sonic/CREDITS create mode 100644 ihub/vendor/github.com/bytedance/sonic/INTRODUCTION.md create mode 100644 ihub/vendor/github.com/bytedance/sonic/LICENSE create mode 100644 ihub/vendor/github.com/bytedance/sonic/Makefile create mode 100644 ihub/vendor/github.com/bytedance/sonic/README.md create mode 100644 ihub/vendor/github.com/bytedance/sonic/api.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/api_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/api_compat.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/asm.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/decode.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/encode.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/error.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/iterator.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/node.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/parser.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/search.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/sort.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/stubs_go115.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/ast/stubs_go120.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/bench-arm.sh create mode 100644 ihub/vendor/github.com/bytedance/sonic/bench-large.png create mode 100644 ihub/vendor/github.com/bytedance/sonic/bench-small.png create mode 100644 ihub/vendor/github.com/bytedance/sonic/bench.py create mode 100644 ihub/vendor/github.com/bytedance/sonic/bench.sh create mode 100644 ihub/vendor/github.com/bytedance/sonic/check_branch_name.sh create mode 100644 ihub/vendor/github.com/bytedance/sonic/compat.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/asm.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/assembler_amd64_go116.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/assembler_amd64_go117.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/compiler.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/debug.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/decoder.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/errors.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go116.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go117.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go117_test.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_test.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/pools.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/primitives.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/stream.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/stubs_go115.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/stubs_go120.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/types.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/decoder/utils.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/asm.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/assembler_amd64_go116.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/assembler_amd64_go117.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/compiler.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/debug_go116.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/debug_go117.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/encoder.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/errors.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/mapiter.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/pools.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/primitives.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/sort.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/stream.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/stubs_go116.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/stubs_go117.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/stubs_go120.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/types.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/encoder/utils.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/go.work create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/caching/asm.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/caching/fcache.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/caching/hashing.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/caching/pcache.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/cpu/features.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/jit/arch_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/jit/asm.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/jit/assembler_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/jit/backend.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/jit/runtime.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/loader/asm.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/loader/funcdata.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go115.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go116.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go118.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/loader/funcdata_go120.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/loader/loader.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/loader/loader_windows.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/avx/native_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/avx/native_amd64.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/avx/native_export_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/avx/native_subr_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/avx2/native_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/avx2/native_amd64.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/avx2/native_export_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/avx2/native_subr_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/dispatch_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/dispatch_amd64.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/fastfloat_amd64_test.tmpl create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/fastint_amd64_test.tmpl create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/native_amd64.tmpl create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/native_amd64_test.tmpl create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/native_export_amd64.tmpl create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/sse/native_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/sse/native_amd64.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/sse/native_export_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/sse/native_subr_amd64.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/native/types/types.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/resolver/asm.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/resolver/resolver.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/resolver/stubs.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/rt/asm_amd64.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/rt/asm_arm64.s create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/rt/fastmem.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/rt/fastvalue.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/rt/gcwb.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/rt/int48.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/internal/rt/stackmap.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/introduction-1.png create mode 100644 ihub/vendor/github.com/bytedance/sonic/introduction-2.png create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/funcdata.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/funcdata_go115.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/funcdata_go118.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/funcdata_go120.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/loader.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/loader_go115.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/loader_go118.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/mmap_unix.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/mmap_windows.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/pcdata.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/loader/stubs.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/option/option.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/other-langs.png create mode 100644 ihub/vendor/github.com/bytedance/sonic/sonic.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/unquote/unquote.go create mode 100644 ihub/vendor/github.com/bytedance/sonic/utf8/utf8.go create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/.gitignore create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/.gitmodules create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/LICENSE create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/Makefile create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/README.md create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/base64x.go create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/cpuid.go create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/faststr.go create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/native_amd64.go create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/native_amd64.s create mode 100644 ihub/vendor/github.com/chenzhuoyu/base64x/native_subr_amd64.go create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/.editorconfig create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/.gitattributes create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/.gitignore create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/.mailmap create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/LICENSE create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/README.md create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/backend_fen.go create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/backend_inotify.go create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/backend_other.go create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/backend_windows.go create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/fsnotify.go create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/system_bsd.go create mode 100644 ihub/vendor/github.com/fsnotify/fsnotify/system_darwin.go create mode 100644 ihub/vendor/github.com/gin-contrib/sse/.travis.yml create mode 100644 ihub/vendor/github.com/gin-contrib/sse/LICENSE create mode 100644 ihub/vendor/github.com/gin-contrib/sse/README.md create mode 100644 ihub/vendor/github.com/gin-contrib/sse/sse-decoder.go create mode 100644 ihub/vendor/github.com/gin-contrib/sse/sse-encoder.go create mode 100644 ihub/vendor/github.com/gin-contrib/sse/writer.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/.gitignore create mode 100644 ihub/vendor/github.com/gin-gonic/gin/.golangci.yml create mode 100644 ihub/vendor/github.com/gin-gonic/gin/.goreleaser.yaml create mode 100644 ihub/vendor/github.com/gin-gonic/gin/AUTHORS.md create mode 100644 ihub/vendor/github.com/gin-gonic/gin/BENCHMARKS.md create mode 100644 ihub/vendor/github.com/gin-gonic/gin/CHANGELOG.md create mode 100644 ihub/vendor/github.com/gin-gonic/gin/CODE_OF_CONDUCT.md create mode 100644 ihub/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md create mode 100644 ihub/vendor/github.com/gin-gonic/gin/LICENSE create mode 100644 ihub/vendor/github.com/gin-gonic/gin/Makefile create mode 100644 ihub/vendor/github.com/gin-gonic/gin/README.md create mode 100644 ihub/vendor/github.com/gin-gonic/gin/any.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/auth.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/any.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/binding.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/default_validator.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/form.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/form_mapping.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/header.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/json.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/msgpack.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/protobuf.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/query.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/toml.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/uri.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/xml.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/binding/yaml.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/codecov.yml create mode 100644 ihub/vendor/github.com/gin-gonic/gin/context.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/context_appengine.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/debug.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/deprecated.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/doc.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/errors.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/fs.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/gin.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/internal/bytesconv/bytesconv.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/internal/json/go_json.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/internal/json/json.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/internal/json/sonic.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/logger.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/mode.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/path.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/recovery.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/any.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/data.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/html.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/json.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/msgpack.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/protobuf.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/reader.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/redirect.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/render.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/text.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/toml.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/xml.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/render/yaml.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/response_writer.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/routergroup.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/test_helpers.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/tree.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/utils.go create mode 100644 ihub/vendor/github.com/gin-gonic/gin/version.go create mode 100644 ihub/vendor/github.com/go-playground/locales/.gitignore create mode 100644 ihub/vendor/github.com/go-playground/locales/.travis.yml create mode 100644 ihub/vendor/github.com/go-playground/locales/LICENSE create mode 100644 ihub/vendor/github.com/go-playground/locales/README.md create mode 100644 ihub/vendor/github.com/go-playground/locales/currency/currency.go create mode 100644 ihub/vendor/github.com/go-playground/locales/logo.png create mode 100644 ihub/vendor/github.com/go-playground/locales/rules.go create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/.gitignore create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/.travis.yml create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/LICENSE create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/Makefile create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/README.md create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/errors.go create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/import_export.go create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/logo.png create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/translator.go create mode 100644 ihub/vendor/github.com/go-playground/universal-translator/universal_translator.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/.gitignore create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/LICENSE create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/MAINTAINERS.md create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/Makefile create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/README.md create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/baked_in.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/cache.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/country_codes.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/currency_codes.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/doc.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/errors.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/field_level.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/logo.png create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/postcode_regexes.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/regexes.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/struct_level.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/translations.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/util.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/validator.go create mode 100644 ihub/vendor/github.com/go-playground/validator/v10/validator_instance.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/.gitignore create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/AUTHORS create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/LICENSE create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/README.md create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/auth.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/buffer.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/collations.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/conncheck.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/conncheck_dummy.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/connection.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/connector.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/const.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/driver.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/dsn.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/errors.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/fields.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/fuzz.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/infile.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/nulltime.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/nulltime_go113.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/nulltime_legacy.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/packets.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/result.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/rows.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/statement.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/transaction.go create mode 100644 ihub/vendor/github.com/go-sql-driver/mysql/utils.go create mode 100644 ihub/vendor/github.com/goccy/go-json/.codecov.yml create mode 100644 ihub/vendor/github.com/goccy/go-json/.gitignore create mode 100644 ihub/vendor/github.com/goccy/go-json/.golangci.yml create mode 100644 ihub/vendor/github.com/goccy/go-json/CHANGELOG.md create mode 100644 ihub/vendor/github.com/goccy/go-json/LICENSE create mode 100644 ihub/vendor/github.com/goccy/go-json/Makefile create mode 100644 ihub/vendor/github.com/goccy/go-json/README.md create mode 100644 ihub/vendor/github.com/goccy/go-json/color.go create mode 100644 ihub/vendor/github.com/goccy/go-json/decode.go create mode 100644 ihub/vendor/github.com/goccy/go-json/docker-compose.yml create mode 100644 ihub/vendor/github.com/goccy/go-json/encode.go create mode 100644 ihub/vendor/github.com/goccy/go-json/error.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/array.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/assign.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/bool.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/bytes.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/compile.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/context.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/float.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/func.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/int.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/interface.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/invalid.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/map.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/number.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/option.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/path.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/ptr.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/slice.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/stream.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/string.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/struct.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/type.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/uint.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/code.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/compact.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/compiler.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/context.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/encoder.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/indent.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/int.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/map112.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/map113.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/opcode.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/option.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/optype.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/query.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/string.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/string_table.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/errors/error.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/runtime/rtype.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go create mode 100644 ihub/vendor/github.com/goccy/go-json/internal/runtime/type.go create mode 100644 ihub/vendor/github.com/goccy/go-json/json.go create mode 100644 ihub/vendor/github.com/goccy/go-json/option.go create mode 100644 ihub/vendor/github.com/goccy/go-json/path.go create mode 100644 ihub/vendor/github.com/goccy/go-json/query.go create mode 100644 ihub/vendor/github.com/google/uuid/.travis.yml create mode 100644 ihub/vendor/github.com/google/uuid/CONTRIBUTING.md create mode 100644 ihub/vendor/github.com/google/uuid/CONTRIBUTORS create mode 100644 ihub/vendor/github.com/google/uuid/LICENSE create mode 100644 ihub/vendor/github.com/google/uuid/README.md create mode 100644 ihub/vendor/github.com/google/uuid/dce.go create mode 100644 ihub/vendor/github.com/google/uuid/doc.go create mode 100644 ihub/vendor/github.com/google/uuid/hash.go create mode 100644 ihub/vendor/github.com/google/uuid/marshal.go create mode 100644 ihub/vendor/github.com/google/uuid/node.go create mode 100644 ihub/vendor/github.com/google/uuid/node_js.go create mode 100644 ihub/vendor/github.com/google/uuid/node_net.go create mode 100644 ihub/vendor/github.com/google/uuid/null.go create mode 100644 ihub/vendor/github.com/google/uuid/sql.go create mode 100644 ihub/vendor/github.com/google/uuid/time.go create mode 100644 ihub/vendor/github.com/google/uuid/util.go create mode 100644 ihub/vendor/github.com/google/uuid/uuid.go create mode 100644 ihub/vendor/github.com/google/uuid/version1.go create mode 100644 ihub/vendor/github.com/google/uuid/version4.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/.gitignore create mode 100644 ihub/vendor/github.com/hashicorp/hcl/.travis.yml create mode 100644 ihub/vendor/github.com/hashicorp/hcl/LICENSE create mode 100644 ihub/vendor/github.com/hashicorp/hcl/Makefile create mode 100644 ihub/vendor/github.com/hashicorp/hcl/README.md create mode 100644 ihub/vendor/github.com/hashicorp/hcl/appveyor.yml create mode 100644 ihub/vendor/github.com/hashicorp/hcl/decoder.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/ast/walk.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/parser/error.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/printer/printer.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/token/position.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/hcl/token/token.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/json/parser/flatten.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/json/parser/parser.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/json/token/position.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/json/token/token.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/lex.go create mode 100644 ihub/vendor/github.com/hashicorp/hcl/parse.go create mode 100644 ihub/vendor/github.com/json-iterator/go/.codecov.yml create mode 100644 ihub/vendor/github.com/json-iterator/go/.gitignore create mode 100644 ihub/vendor/github.com/json-iterator/go/.travis.yml create mode 100644 ihub/vendor/github.com/json-iterator/go/Gopkg.lock create mode 100644 ihub/vendor/github.com/json-iterator/go/Gopkg.toml create mode 100644 ihub/vendor/github.com/json-iterator/go/LICENSE create mode 100644 ihub/vendor/github.com/json-iterator/go/README.md create mode 100644 ihub/vendor/github.com/json-iterator/go/adapter.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_array.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_bool.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_float.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_int32.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_int64.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_invalid.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_nil.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_number.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_object.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_str.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_uint32.go create mode 100644 ihub/vendor/github.com/json-iterator/go/any_uint64.go create mode 100644 ihub/vendor/github.com/json-iterator/go/build.sh create mode 100644 ihub/vendor/github.com/json-iterator/go/config.go create mode 100644 ihub/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md create mode 100644 ihub/vendor/github.com/json-iterator/go/iter.go create mode 100644 ihub/vendor/github.com/json-iterator/go/iter_array.go create mode 100644 ihub/vendor/github.com/json-iterator/go/iter_float.go create mode 100644 ihub/vendor/github.com/json-iterator/go/iter_int.go create mode 100644 ihub/vendor/github.com/json-iterator/go/iter_object.go create mode 100644 ihub/vendor/github.com/json-iterator/go/iter_skip.go create mode 100644 ihub/vendor/github.com/json-iterator/go/iter_skip_sloppy.go create mode 100644 ihub/vendor/github.com/json-iterator/go/iter_skip_strict.go create mode 100644 ihub/vendor/github.com/json-iterator/go/iter_str.go create mode 100644 ihub/vendor/github.com/json-iterator/go/jsoniter.go create mode 100644 ihub/vendor/github.com/json-iterator/go/pool.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_array.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_dynamic.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_extension.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_json_number.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_json_raw_message.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_map.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_marshaler.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_native.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_optional.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_slice.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_struct_decoder.go create mode 100644 ihub/vendor/github.com/json-iterator/go/reflect_struct_encoder.go create mode 100644 ihub/vendor/github.com/json-iterator/go/stream.go create mode 100644 ihub/vendor/github.com/json-iterator/go/stream_float.go create mode 100644 ihub/vendor/github.com/json-iterator/go/stream_int.go create mode 100644 ihub/vendor/github.com/json-iterator/go/stream_str.go create mode 100644 ihub/vendor/github.com/json-iterator/go/test.sh create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/.gitignore create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/.goreleaser.yml create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/CONTRIBUTING.txt create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/LICENSE create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/README.md create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/cpuid.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/cpuid_386.s create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/cpuid_amd64.s create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/cpuid_arm64.s create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/detect_arm64.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/detect_ref.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/detect_x86.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/featureid_string.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/os_other_arm64.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/os_safe_linux_arm64.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/os_unsafe_linux_arm64.go create mode 100644 ihub/vendor/github.com/klauspost/cpuid/v2/test-architectures.sh create mode 100644 ihub/vendor/github.com/leodido/go-urn/.gitignore create mode 100644 ihub/vendor/github.com/leodido/go-urn/.travis.yml create mode 100644 ihub/vendor/github.com/leodido/go-urn/LICENSE create mode 100644 ihub/vendor/github.com/leodido/go-urn/README.md create mode 100644 ihub/vendor/github.com/leodido/go-urn/machine.go create mode 100644 ihub/vendor/github.com/leodido/go-urn/machine.go.rl create mode 100644 ihub/vendor/github.com/leodido/go-urn/makefile create mode 100644 ihub/vendor/github.com/leodido/go-urn/urn.go create mode 100644 ihub/vendor/github.com/magiconair/properties/.gitignore create mode 100644 ihub/vendor/github.com/magiconair/properties/CHANGELOG.md create mode 100644 ihub/vendor/github.com/magiconair/properties/LICENSE.md create mode 100644 ihub/vendor/github.com/magiconair/properties/README.md create mode 100644 ihub/vendor/github.com/magiconair/properties/decode.go create mode 100644 ihub/vendor/github.com/magiconair/properties/doc.go create mode 100644 ihub/vendor/github.com/magiconair/properties/integrate.go create mode 100644 ihub/vendor/github.com/magiconair/properties/lex.go create mode 100644 ihub/vendor/github.com/magiconair/properties/load.go create mode 100644 ihub/vendor/github.com/magiconair/properties/parser.go create mode 100644 ihub/vendor/github.com/magiconair/properties/properties.go create mode 100644 ihub/vendor/github.com/magiconair/properties/rangecheck.go create mode 100644 ihub/vendor/github.com/mattn/go-isatty/LICENSE create mode 100644 ihub/vendor/github.com/mattn/go-isatty/README.md create mode 100644 ihub/vendor/github.com/mattn/go-isatty/doc.go create mode 100644 ihub/vendor/github.com/mattn/go-isatty/go.test.sh create mode 100644 ihub/vendor/github.com/mattn/go-isatty/isatty_bsd.go create mode 100644 ihub/vendor/github.com/mattn/go-isatty/isatty_others.go create mode 100644 ihub/vendor/github.com/mattn/go-isatty/isatty_plan9.go create mode 100644 ihub/vendor/github.com/mattn/go-isatty/isatty_solaris.go create mode 100644 ihub/vendor/github.com/mattn/go-isatty/isatty_tcgets.go create mode 100644 ihub/vendor/github.com/mattn/go-isatty/isatty_windows.go create mode 100644 ihub/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md create mode 100644 ihub/vendor/github.com/mitchellh/mapstructure/LICENSE create mode 100644 ihub/vendor/github.com/mitchellh/mapstructure/README.md create mode 100644 ihub/vendor/github.com/mitchellh/mapstructure/decode_hooks.go create mode 100644 ihub/vendor/github.com/mitchellh/mapstructure/error.go create mode 100644 ihub/vendor/github.com/mitchellh/mapstructure/mapstructure.go create mode 100644 ihub/vendor/github.com/modern-go/concurrent/.gitignore create mode 100644 ihub/vendor/github.com/modern-go/concurrent/.travis.yml create mode 100644 ihub/vendor/github.com/modern-go/concurrent/LICENSE create mode 100644 ihub/vendor/github.com/modern-go/concurrent/README.md create mode 100644 ihub/vendor/github.com/modern-go/concurrent/executor.go create mode 100644 ihub/vendor/github.com/modern-go/concurrent/go_above_19.go create mode 100644 ihub/vendor/github.com/modern-go/concurrent/go_below_19.go create mode 100644 ihub/vendor/github.com/modern-go/concurrent/log.go create mode 100644 ihub/vendor/github.com/modern-go/concurrent/test.sh create mode 100644 ihub/vendor/github.com/modern-go/concurrent/unbounded_executor.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/.gitignore create mode 100644 ihub/vendor/github.com/modern-go/reflect2/.travis.yml create mode 100644 ihub/vendor/github.com/modern-go/reflect2/Gopkg.lock create mode 100644 ihub/vendor/github.com/modern-go/reflect2/Gopkg.toml create mode 100644 ihub/vendor/github.com/modern-go/reflect2/LICENSE create mode 100644 ihub/vendor/github.com/modern-go/reflect2/README.md create mode 100644 ihub/vendor/github.com/modern-go/reflect2/go_above_118.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/go_above_19.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/go_below_118.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/reflect2.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/reflect2_amd64.s create mode 100644 ihub/vendor/github.com/modern-go/reflect2/reflect2_kind.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/relfect2_386.s create mode 100644 ihub/vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s create mode 100644 ihub/vendor/github.com/modern-go/reflect2/relfect2_arm.s create mode 100644 ihub/vendor/github.com/modern-go/reflect2/relfect2_arm64.s create mode 100644 ihub/vendor/github.com/modern-go/reflect2/relfect2_mips64x.s create mode 100644 ihub/vendor/github.com/modern-go/reflect2/relfect2_mipsx.s create mode 100644 ihub/vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s create mode 100644 ihub/vendor/github.com/modern-go/reflect2/relfect2_s390x.s create mode 100644 ihub/vendor/github.com/modern-go/reflect2/safe_field.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/safe_map.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/safe_slice.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/safe_struct.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/safe_type.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/type_map.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_array.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_eface.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_field.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_iface.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_link.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_map.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_ptr.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_slice.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_struct.go create mode 100644 ihub/vendor/github.com/modern-go/reflect2/unsafe_type.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/.dockerignore create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/.gitattributes create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/.gitignore create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/.golangci.toml create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/Dockerfile create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/LICENSE create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/README.md create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/SECURITY.md create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/ci.sh create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/decode.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/doc.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/errors.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/internal/danger/danger.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/internal/danger/typeid.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/internal/tracker/tracker.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/localtime.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/marshaler.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/strict.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/toml.abnf create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/types.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/unstable/builder.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/unstable/doc.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/unstable/kind.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/unstable/parser.go create mode 100644 ihub/vendor/github.com/pelletier/go-toml/v2/unstable/scanner.go create mode 100644 ihub/vendor/github.com/segmentio/fasthash/LICENSE create mode 100644 ihub/vendor/github.com/segmentio/fasthash/fnv1a/hash.go create mode 100644 ihub/vendor/github.com/segmentio/fasthash/fnv1a/hash32.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/.gitignore create mode 100644 ihub/vendor/github.com/sirupsen/logrus/.golangci.yml create mode 100644 ihub/vendor/github.com/sirupsen/logrus/.travis.yml create mode 100644 ihub/vendor/github.com/sirupsen/logrus/CHANGELOG.md create mode 100644 ihub/vendor/github.com/sirupsen/logrus/LICENSE create mode 100644 ihub/vendor/github.com/sirupsen/logrus/README.md create mode 100644 ihub/vendor/github.com/sirupsen/logrus/alt_exit.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/appveyor.yml create mode 100644 ihub/vendor/github.com/sirupsen/logrus/buffer_pool.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/doc.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/entry.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/exported.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/formatter.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/hooks.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/json_formatter.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/logger.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/logrus.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/terminal_check_js.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/terminal_check_unix.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/terminal_check_windows.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/text_formatter.go create mode 100644 ihub/vendor/github.com/sirupsen/logrus/writer.go create mode 100644 ihub/vendor/github.com/spf13/afero/.gitignore create mode 100644 ihub/vendor/github.com/spf13/afero/LICENSE.txt create mode 100644 ihub/vendor/github.com/spf13/afero/README.md create mode 100644 ihub/vendor/github.com/spf13/afero/afero.go create mode 100644 ihub/vendor/github.com/spf13/afero/appveyor.yml create mode 100644 ihub/vendor/github.com/spf13/afero/basepath.go create mode 100644 ihub/vendor/github.com/spf13/afero/cacheOnReadFs.go create mode 100644 ihub/vendor/github.com/spf13/afero/const_bsds.go create mode 100644 ihub/vendor/github.com/spf13/afero/const_win_unix.go create mode 100644 ihub/vendor/github.com/spf13/afero/copyOnWriteFs.go create mode 100644 ihub/vendor/github.com/spf13/afero/httpFs.go create mode 100644 ihub/vendor/github.com/spf13/afero/internal/common/adapters.go create mode 100644 ihub/vendor/github.com/spf13/afero/iofs.go create mode 100644 ihub/vendor/github.com/spf13/afero/ioutil.go create mode 100644 ihub/vendor/github.com/spf13/afero/lstater.go create mode 100644 ihub/vendor/github.com/spf13/afero/match.go create mode 100644 ihub/vendor/github.com/spf13/afero/mem/dir.go create mode 100644 ihub/vendor/github.com/spf13/afero/mem/dirmap.go create mode 100644 ihub/vendor/github.com/spf13/afero/mem/file.go create mode 100644 ihub/vendor/github.com/spf13/afero/memmap.go create mode 100644 ihub/vendor/github.com/spf13/afero/os.go create mode 100644 ihub/vendor/github.com/spf13/afero/path.go create mode 100644 ihub/vendor/github.com/spf13/afero/readonlyfs.go create mode 100644 ihub/vendor/github.com/spf13/afero/regexpfs.go create mode 100644 ihub/vendor/github.com/spf13/afero/symlink.go create mode 100644 ihub/vendor/github.com/spf13/afero/unionFile.go create mode 100644 ihub/vendor/github.com/spf13/afero/util.go create mode 100644 ihub/vendor/github.com/spf13/cast/.gitignore create mode 100644 ihub/vendor/github.com/spf13/cast/LICENSE create mode 100644 ihub/vendor/github.com/spf13/cast/Makefile create mode 100644 ihub/vendor/github.com/spf13/cast/README.md create mode 100644 ihub/vendor/github.com/spf13/cast/cast.go create mode 100644 ihub/vendor/github.com/spf13/cast/caste.go create mode 100644 ihub/vendor/github.com/spf13/cast/timeformattype_string.go create mode 100644 ihub/vendor/github.com/spf13/jwalterweatherman/.gitignore create mode 100644 ihub/vendor/github.com/spf13/jwalterweatherman/LICENSE create mode 100644 ihub/vendor/github.com/spf13/jwalterweatherman/README.md create mode 100644 ihub/vendor/github.com/spf13/jwalterweatherman/default_notepad.go create mode 100644 ihub/vendor/github.com/spf13/jwalterweatherman/log_counter.go create mode 100644 ihub/vendor/github.com/spf13/jwalterweatherman/notepad.go create mode 100644 ihub/vendor/github.com/spf13/pflag/.gitignore create mode 100644 ihub/vendor/github.com/spf13/pflag/.travis.yml create mode 100644 ihub/vendor/github.com/spf13/pflag/LICENSE create mode 100644 ihub/vendor/github.com/spf13/pflag/README.md create mode 100644 ihub/vendor/github.com/spf13/pflag/bool.go create mode 100644 ihub/vendor/github.com/spf13/pflag/bool_slice.go create mode 100644 ihub/vendor/github.com/spf13/pflag/bytes.go create mode 100644 ihub/vendor/github.com/spf13/pflag/count.go create mode 100644 ihub/vendor/github.com/spf13/pflag/duration.go create mode 100644 ihub/vendor/github.com/spf13/pflag/duration_slice.go create mode 100644 ihub/vendor/github.com/spf13/pflag/flag.go create mode 100644 ihub/vendor/github.com/spf13/pflag/float32.go create mode 100644 ihub/vendor/github.com/spf13/pflag/float32_slice.go create mode 100644 ihub/vendor/github.com/spf13/pflag/float64.go create mode 100644 ihub/vendor/github.com/spf13/pflag/float64_slice.go create mode 100644 ihub/vendor/github.com/spf13/pflag/golangflag.go create mode 100644 ihub/vendor/github.com/spf13/pflag/int.go create mode 100644 ihub/vendor/github.com/spf13/pflag/int16.go create mode 100644 ihub/vendor/github.com/spf13/pflag/int32.go create mode 100644 ihub/vendor/github.com/spf13/pflag/int32_slice.go create mode 100644 ihub/vendor/github.com/spf13/pflag/int64.go create mode 100644 ihub/vendor/github.com/spf13/pflag/int64_slice.go create mode 100644 ihub/vendor/github.com/spf13/pflag/int8.go create mode 100644 ihub/vendor/github.com/spf13/pflag/int_slice.go create mode 100644 ihub/vendor/github.com/spf13/pflag/ip.go create mode 100644 ihub/vendor/github.com/spf13/pflag/ip_slice.go create mode 100644 ihub/vendor/github.com/spf13/pflag/ipmask.go create mode 100644 ihub/vendor/github.com/spf13/pflag/ipnet.go create mode 100644 ihub/vendor/github.com/spf13/pflag/string.go create mode 100644 ihub/vendor/github.com/spf13/pflag/string_array.go create mode 100644 ihub/vendor/github.com/spf13/pflag/string_slice.go create mode 100644 ihub/vendor/github.com/spf13/pflag/string_to_int.go create mode 100644 ihub/vendor/github.com/spf13/pflag/string_to_int64.go create mode 100644 ihub/vendor/github.com/spf13/pflag/string_to_string.go create mode 100644 ihub/vendor/github.com/spf13/pflag/uint.go create mode 100644 ihub/vendor/github.com/spf13/pflag/uint16.go create mode 100644 ihub/vendor/github.com/spf13/pflag/uint32.go create mode 100644 ihub/vendor/github.com/spf13/pflag/uint64.go create mode 100644 ihub/vendor/github.com/spf13/pflag/uint8.go create mode 100644 ihub/vendor/github.com/spf13/pflag/uint_slice.go create mode 100644 ihub/vendor/github.com/spf13/viper/.editorconfig create mode 100644 ihub/vendor/github.com/spf13/viper/.gitignore create mode 100644 ihub/vendor/github.com/spf13/viper/.golangci.yaml create mode 100644 ihub/vendor/github.com/spf13/viper/LICENSE create mode 100644 ihub/vendor/github.com/spf13/viper/Makefile create mode 100644 ihub/vendor/github.com/spf13/viper/README.md create mode 100644 ihub/vendor/github.com/spf13/viper/TROUBLESHOOTING.md create mode 100644 ihub/vendor/github.com/spf13/viper/experimental_logger.go create mode 100644 ihub/vendor/github.com/spf13/viper/flags.go create mode 100644 ihub/vendor/github.com/spf13/viper/fs.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/decoder.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/encoder.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/error.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/ini/codec.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/json/codec.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go create mode 100644 ihub/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go create mode 100644 ihub/vendor/github.com/spf13/viper/logger.go create mode 100644 ihub/vendor/github.com/spf13/viper/util.go create mode 100644 ihub/vendor/github.com/spf13/viper/viper.go create mode 100644 ihub/vendor/github.com/spf13/viper/viper_go1_15.go create mode 100644 ihub/vendor/github.com/spf13/viper/viper_go1_16.go create mode 100644 ihub/vendor/github.com/spf13/viper/watch.go create mode 100644 ihub/vendor/github.com/spf13/viper/watch_unsupported.go create mode 100644 ihub/vendor/github.com/subosito/gotenv/.env create mode 100644 ihub/vendor/github.com/subosito/gotenv/.env.invalid create mode 100644 ihub/vendor/github.com/subosito/gotenv/.gitignore create mode 100644 ihub/vendor/github.com/subosito/gotenv/.golangci.yaml create mode 100644 ihub/vendor/github.com/subosito/gotenv/CHANGELOG.md create mode 100644 ihub/vendor/github.com/subosito/gotenv/LICENSE create mode 100644 ihub/vendor/github.com/subosito/gotenv/README.md create mode 100644 ihub/vendor/github.com/subosito/gotenv/gotenv.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/LICENSE create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/sm2/p256.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/sm2/sm2.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/sm2/utils.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/sm3/ifile create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/sm3/sm3.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/x509/ber.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/x509/cert_pool.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/x509/pkcs1.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/x509/pkcs7.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/x509/pkcs8.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/x509/utils.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/x509/verify.go create mode 100644 ihub/vendor/github.com/tjfoc/gmsm/x509/x509.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/LICENSE create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arch.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arm.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arm64.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/asm/arch/mips.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/asm/arch/ppc64.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/asm/arch/riscv64.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/asm/arch/s390x.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/bio/buf.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/bio/buf_mmap.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/bio/buf_nommap.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/bio/must.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/dwarf/dwarf.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/dwarf/dwarf_defs.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/goobj/builtin.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/goobj/builtinlist.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/goobj/funcinfo.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/goobj/objfile.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/abi_string.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/addrtype_string.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm/a.out.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm/anames.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm/anames5.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm/asm5.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm/list5.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm/obj5.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/a.out.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/anames.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/anames7.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/asm7.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/doc.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/list7.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/obj7.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/sysRegEnc.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/data.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/dwarf.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/go.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/inl.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/ld.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/line.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/link.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/mips/a.out.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/mips/anames.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/mips/anames0.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/mips/asm0.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/mips/list0.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/mips/obj0.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/objfile.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/pass.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/pcln.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/plist.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/a.out.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/anames.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/anames9.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/asm9.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/doc.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/list9.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/obj9.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/anames.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/cpu.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/inst.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/list.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/obj.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/a.out.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/anames.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/anamesz.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/asmz.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/condition_code.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/listz.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/objz.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/rotate.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/vector.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/sym.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/textflag.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/util.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/wasm/a.out.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/wasm/anames.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/wasm/wasmobj.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/a.out.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/aenum.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/anames.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/asm6.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/avx_optabs.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/evex.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/list6.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/obj6.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/obj/x86/ytab.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/autotype.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/flag.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/funcdata.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/funcid.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/head.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/line.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/path.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/reloctype.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/reloctype_string.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/stack.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/symkind.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/symkind_string.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/typekind.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/objabi/util.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/src/pos.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/src/xpos.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/sys/arch.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/sys/supported.go create mode 100644 ihub/vendor/github.com/twitchyliquid64/golang-asm/unsafeheader/unsafeheader.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/0_importpath.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/LICENSE create mode 100644 ihub/vendor/github.com/ugorji/go/codec/README.md create mode 100644 ihub/vendor/github.com/ugorji/go/codec/binc.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/build.sh create mode 100644 ihub/vendor/github.com/ugorji/go/codec/cbor.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/codecgen.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/decimal.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/decode.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/doc.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/encode.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/fast-path.generated.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl create mode 100644 ihub/vendor/github.com/ugorji/go/codec/fast-path.not.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl create mode 100644 ihub/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl create mode 100644 ihub/vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl create mode 100644 ihub/vendor/github.com/ugorji/go/codec/gen-helper.generated.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl create mode 100644 ihub/vendor/github.com/ugorji/go/codec/gen.generated.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/gen.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_fmt_time_gte_go15.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_fmt_time_lt_go15.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_growslice_unsafe_gte_go120.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_growslice_unsafe_lt_go120.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go110.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_makemap_not_unsafe_gte_go110.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_makemap_unsafe_gte_go110.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_maprange_gte_go112.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_maprange_lt_go112.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/helper.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/helper.s create mode 100644 ihub/vendor/github.com/ugorji/go/codec/helper_internal.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/helper_not_unsafe_not_gc.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/helper_unsafe.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/helper_unsafe_compiler_gc.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/helper_unsafe_compiler_not_gc.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/json.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl create mode 100644 ihub/vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl create mode 100644 ihub/vendor/github.com/ugorji/go/codec/msgpack.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/reader.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/register_ext.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/rpc.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/simple.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/sort-slice.generated.go create mode 100644 ihub/vendor/github.com/ugorji/go/codec/sort-slice.go.tmpl create mode 100644 ihub/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json create mode 100644 ihub/vendor/github.com/ugorji/go/codec/test.py create mode 100644 ihub/vendor/github.com/ugorji/go/codec/writer.go create mode 100644 ihub/vendor/github.com/upper/db/v4/.gitignore create mode 100644 ihub/vendor/github.com/upper/db/v4/LICENSE create mode 100644 ihub/vendor/github.com/upper/db/v4/Makefile create mode 100644 ihub/vendor/github.com/upper/db/v4/README.md create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter.go create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter/mysql/Makefile create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter/mysql/README.md create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter/mysql/collection.go create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter/mysql/connection.go create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter/mysql/custom_types.go create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter/mysql/database.go create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter/mysql/docker-compose.yml create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter/mysql/mysql.go create mode 100644 ihub/vendor/github.com/upper/db/v4/adapter/mysql/template.go create mode 100644 ihub/vendor/github.com/upper/db/v4/clauses.go create mode 100644 ihub/vendor/github.com/upper/db/v4/collection.go create mode 100644 ihub/vendor/github.com/upper/db/v4/comparison.go create mode 100644 ihub/vendor/github.com/upper/db/v4/cond.go create mode 100644 ihub/vendor/github.com/upper/db/v4/connection_url.go create mode 100644 ihub/vendor/github.com/upper/db/v4/db.go create mode 100644 ihub/vendor/github.com/upper/db/v4/errors.go create mode 100644 ihub/vendor/github.com/upper/db/v4/function.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/adapter/comparison.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/adapter/constraint.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/adapter/func.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/adapter/logical_expr.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/adapter/raw.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/cache/cache.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/cache/hash.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/cache/interface.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/immutable/immutable.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/reflectx/LICENSE create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/reflectx/README.md create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/reflectx/reflect.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/collection.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/compat/query.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/compat/query_go18.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/column.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/column_value.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/columns.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/database.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/default.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/errors.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/group_by.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/interfaces.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/join.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/order_by.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/raw.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/returning.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/statement.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/table.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/template.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/types.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/utilities.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/value.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/exql/where.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/hash.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/record.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/result.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/session.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/sqladapter.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqladapter/statement.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/batch.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/builder.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/comparison.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/convert.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/custom_types.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/delete.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/errors.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/fetch.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/insert.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/paginate.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/scanner.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/select.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/sqlbuilder.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/template.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/update.go create mode 100644 ihub/vendor/github.com/upper/db/v4/internal/sqlbuilder/wrapper.go create mode 100644 ihub/vendor/github.com/upper/db/v4/intersection.go create mode 100644 ihub/vendor/github.com/upper/db/v4/iterator.go create mode 100644 ihub/vendor/github.com/upper/db/v4/logger.go create mode 100644 ihub/vendor/github.com/upper/db/v4/marshal.go create mode 100644 ihub/vendor/github.com/upper/db/v4/raw.go create mode 100644 ihub/vendor/github.com/upper/db/v4/record.go create mode 100644 ihub/vendor/github.com/upper/db/v4/result.go create mode 100644 ihub/vendor/github.com/upper/db/v4/session.go create mode 100644 ihub/vendor/github.com/upper/db/v4/settings.go create mode 100644 ihub/vendor/github.com/upper/db/v4/sql.go create mode 100644 ihub/vendor/github.com/upper/db/v4/store.go create mode 100644 ihub/vendor/github.com/upper/db/v4/union.go create mode 100644 ihub/vendor/golang.org/x/arch/AUTHORS create mode 100644 ihub/vendor/golang.org/x/arch/CONTRIBUTORS create mode 100644 ihub/vendor/golang.org/x/arch/LICENSE create mode 100644 ihub/vendor/golang.org/x/arch/PATENTS create mode 100644 ihub/vendor/golang.org/x/arch/x86/x86asm/Makefile create mode 100644 ihub/vendor/golang.org/x/arch/x86/x86asm/decode.go create mode 100644 ihub/vendor/golang.org/x/arch/x86/x86asm/gnu.go create mode 100644 ihub/vendor/golang.org/x/arch/x86/x86asm/inst.go create mode 100644 ihub/vendor/golang.org/x/arch/x86/x86asm/intel.go create mode 100644 ihub/vendor/golang.org/x/arch/x86/x86asm/plan9x.go create mode 100644 ihub/vendor/golang.org/x/arch/x86/x86asm/tables.go create mode 100644 ihub/vendor/golang.org/x/crypto/LICENSE create mode 100644 ihub/vendor/golang.org/x/crypto/PATENTS create mode 100644 ihub/vendor/golang.org/x/crypto/ripemd160/ripemd160.go create mode 100644 ihub/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/doc.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/hashes.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/hashes_generic.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/keccakf.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/register.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/sha3.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/sha3_s390x.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/sha3_s390x.s create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/shake.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/shake_generic.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/xor.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/xor_generic.go create mode 100644 ihub/vendor/golang.org/x/crypto/sha3/xor_unaligned.go create mode 100644 ihub/vendor/golang.org/x/net/LICENSE create mode 100644 ihub/vendor/golang.org/x/net/PATENTS create mode 100644 ihub/vendor/golang.org/x/net/http/httpguts/guts.go create mode 100644 ihub/vendor/golang.org/x/net/http/httpguts/httplex.go create mode 100644 ihub/vendor/golang.org/x/net/http2/.gitignore create mode 100644 ihub/vendor/golang.org/x/net/http2/Dockerfile create mode 100644 ihub/vendor/golang.org/x/net/http2/Makefile create mode 100644 ihub/vendor/golang.org/x/net/http2/ascii.go create mode 100644 ihub/vendor/golang.org/x/net/http2/ciphers.go create mode 100644 ihub/vendor/golang.org/x/net/http2/client_conn_pool.go create mode 100644 ihub/vendor/golang.org/x/net/http2/databuffer.go create mode 100644 ihub/vendor/golang.org/x/net/http2/errors.go create mode 100644 ihub/vendor/golang.org/x/net/http2/flow.go create mode 100644 ihub/vendor/golang.org/x/net/http2/frame.go create mode 100644 ihub/vendor/golang.org/x/net/http2/go111.go create mode 100644 ihub/vendor/golang.org/x/net/http2/go115.go create mode 100644 ihub/vendor/golang.org/x/net/http2/go118.go create mode 100644 ihub/vendor/golang.org/x/net/http2/gotrack.go create mode 100644 ihub/vendor/golang.org/x/net/http2/h2c/h2c.go create mode 100644 ihub/vendor/golang.org/x/net/http2/headermap.go create mode 100644 ihub/vendor/golang.org/x/net/http2/hpack/encode.go create mode 100644 ihub/vendor/golang.org/x/net/http2/hpack/hpack.go create mode 100644 ihub/vendor/golang.org/x/net/http2/hpack/huffman.go create mode 100644 ihub/vendor/golang.org/x/net/http2/hpack/static_table.go create mode 100644 ihub/vendor/golang.org/x/net/http2/hpack/tables.go create mode 100644 ihub/vendor/golang.org/x/net/http2/http2.go create mode 100644 ihub/vendor/golang.org/x/net/http2/not_go111.go create mode 100644 ihub/vendor/golang.org/x/net/http2/not_go115.go create mode 100644 ihub/vendor/golang.org/x/net/http2/not_go118.go create mode 100644 ihub/vendor/golang.org/x/net/http2/pipe.go create mode 100644 ihub/vendor/golang.org/x/net/http2/server.go create mode 100644 ihub/vendor/golang.org/x/net/http2/transport.go create mode 100644 ihub/vendor/golang.org/x/net/http2/write.go create mode 100644 ihub/vendor/golang.org/x/net/http2/writesched.go create mode 100644 ihub/vendor/golang.org/x/net/http2/writesched_priority.go create mode 100644 ihub/vendor/golang.org/x/net/http2/writesched_random.go create mode 100644 ihub/vendor/golang.org/x/net/idna/go118.go create mode 100644 ihub/vendor/golang.org/x/net/idna/idna10.0.0.go create mode 100644 ihub/vendor/golang.org/x/net/idna/idna9.0.0.go create mode 100644 ihub/vendor/golang.org/x/net/idna/pre_go118.go create mode 100644 ihub/vendor/golang.org/x/net/idna/punycode.go create mode 100644 ihub/vendor/golang.org/x/net/idna/tables10.0.0.go create mode 100644 ihub/vendor/golang.org/x/net/idna/tables11.0.0.go create mode 100644 ihub/vendor/golang.org/x/net/idna/tables12.0.0.go create mode 100644 ihub/vendor/golang.org/x/net/idna/tables13.0.0.go create mode 100644 ihub/vendor/golang.org/x/net/idna/tables9.0.0.go create mode 100644 ihub/vendor/golang.org/x/net/idna/trie.go create mode 100644 ihub/vendor/golang.org/x/net/idna/trieval.go create mode 100644 ihub/vendor/golang.org/x/sys/LICENSE create mode 100644 ihub/vendor/golang.org/x/sys/PATENTS create mode 100644 ihub/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s create mode 100644 ihub/vendor/golang.org/x/sys/cpu/byteorder.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_aix.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_arm64.s create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_linux_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_loong64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_mips64x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_mipsx.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_other_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_ppc64x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_s390x.s create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_wasm.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_x86.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_x86.s create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_zos.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/endian_big.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/endian_little.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/hwcap_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/parse.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go create mode 100644 ihub/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go create mode 100644 ihub/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/.gitignore create mode 100644 ihub/vendor/golang.org/x/sys/unix/README.md create mode 100644 ihub/vendor/golang.org/x/sys/unix/affinity_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/aliases.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_bsd_386.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_bsd_amd64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_bsd_arm.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_bsd_arm64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_386.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_amd64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_arm.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_arm64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_loong64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_linux_s390x.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/asm_zos_s390x.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/bluetooth_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/cap_freebsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/constants.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dev_aix_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dev_darwin.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dev_dragonfly.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dev_freebsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dev_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dev_netbsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dev_openbsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dev_zos.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/dirent.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/endian_big.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/endian_little.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/env_unix.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/epoll_zos.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/fcntl.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/fcntl_darwin.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/fdset.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/fstatfs_zos.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/gccgo.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/gccgo_c.c create mode 100644 ihub/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ifreq_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ioctl.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ioctl_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ioctl_zos.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/mkall.sh create mode 100644 ihub/vendor/golang.org/x/sys/unix/mkerrors.sh create mode 100644 ihub/vendor/golang.org/x/sys/unix/pagesize_unix.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/pledge_openbsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ptrace_darwin.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ptrace_ios.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/race.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/race0.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/readdirent_getdents.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/sockcmsg_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/sockcmsg_unix.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_aix.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_bsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_darwin.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_dragonfly.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_freebsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_hurd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_hurd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_illumos.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_alarm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_gc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_netbsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_openbsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_solaris.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_unix.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_unix_gc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/sysvshm_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/sysvshm_unix.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/timestruct.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/unveil_openbsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/xattr_bsd.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_freebsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_loong64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_freebsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_aix_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/aliases.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/dll_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/empty.s create mode 100644 ihub/vendor/golang.org/x/sys/windows/env_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/eventlog.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/exec_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/memory_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/mkerrors.bash create mode 100644 ihub/vendor/golang.org/x/sys/windows/mkknownfolderids.bash create mode 100644 ihub/vendor/golang.org/x/sys/windows/mksyscall.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/race.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/race0.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/security_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/service.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/setupapi_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/str.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/syscall.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/syscall_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/types_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/types_windows_386.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/types_windows_amd64.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/types_windows_arm.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/types_windows_arm64.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/zerrors_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/zknownfolderids_windows.go create mode 100644 ihub/vendor/golang.org/x/sys/windows/zsyscall_windows.go create mode 100644 ihub/vendor/golang.org/x/text/LICENSE create mode 100644 ihub/vendor/golang.org/x/text/PATENTS create mode 100644 ihub/vendor/golang.org/x/text/internal/language/common.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/compact.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/compact/compact.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/compact/language.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/compact/parents.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/compact/tables.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/compact/tags.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/compose.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/coverage.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/language.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/lookup.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/match.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/parse.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/tables.go create mode 100644 ihub/vendor/golang.org/x/text/internal/language/tags.go create mode 100644 ihub/vendor/golang.org/x/text/internal/tag/tag.go create mode 100644 ihub/vendor/golang.org/x/text/language/coverage.go create mode 100644 ihub/vendor/golang.org/x/text/language/doc.go create mode 100644 ihub/vendor/golang.org/x/text/language/language.go create mode 100644 ihub/vendor/golang.org/x/text/language/match.go create mode 100644 ihub/vendor/golang.org/x/text/language/parse.go create mode 100644 ihub/vendor/golang.org/x/text/language/tables.go create mode 100644 ihub/vendor/golang.org/x/text/language/tags.go create mode 100644 ihub/vendor/golang.org/x/text/runes/cond.go create mode 100644 ihub/vendor/golang.org/x/text/runes/runes.go create mode 100644 ihub/vendor/golang.org/x/text/secure/bidirule/bidirule.go create mode 100644 ihub/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/transform/transform.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/bidi.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/bracket.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/core.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/prop.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/bidi/trieval.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/composition.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/forminfo.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/input.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/iter.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/normalize.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/readwriter.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/tables12.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/transform.go create mode 100644 ihub/vendor/golang.org/x/text/unicode/norm/trie.go create mode 100644 ihub/vendor/google.golang.org/protobuf/LICENSE create mode 100644 ihub/vendor/google.golang.org/protobuf/PATENTS create mode 100644 ihub/vendor/google.golang.org/protobuf/encoding/protowire/wire.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/detrand/rand.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/errors/errors.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/errors/is_go112.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/errors/is_go113.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/flags/flags.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/any_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/api_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/doc.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/duration_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/empty_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/field_mask_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/goname.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/map_entry.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/source_context_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/struct_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/timestamp_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/type_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/wrappers.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/genid/wrappers_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/order/order.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/order/range.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/pragma/pragma.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/strs/strings.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/strs/strings_pure.go create mode 100644 ihub/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/checkinit.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/decode.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/decode_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/doc.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/encode.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/encode_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/equal.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/extension.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/merge.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/messageset.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/proto.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/proto_methods.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/proto_reflect.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/reset.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/size.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/size_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/proto/wrappers.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go create mode 100644 ihub/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go create mode 100644 ihub/vendor/google.golang.org/protobuf/runtime/protoiface/legacy.go create mode 100644 ihub/vendor/google.golang.org/protobuf/runtime/protoiface/methods.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/.editorconfig create mode 100644 ihub/vendor/gopkg.in/ini.v1/.gitignore create mode 100644 ihub/vendor/gopkg.in/ini.v1/.golangci.yml create mode 100644 ihub/vendor/gopkg.in/ini.v1/LICENSE create mode 100644 ihub/vendor/gopkg.in/ini.v1/Makefile create mode 100644 ihub/vendor/gopkg.in/ini.v1/README.md create mode 100644 ihub/vendor/gopkg.in/ini.v1/codecov.yml create mode 100644 ihub/vendor/gopkg.in/ini.v1/data_source.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/deprecated.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/error.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/file.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/helper.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/ini.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/key.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/parser.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/section.go create mode 100644 ihub/vendor/gopkg.in/ini.v1/struct.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/LICENSE create mode 100644 ihub/vendor/gopkg.in/yaml.v3/NOTICE create mode 100644 ihub/vendor/gopkg.in/yaml.v3/README.md create mode 100644 ihub/vendor/gopkg.in/yaml.v3/apic.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/decode.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/emitterc.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/encode.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/parserc.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/readerc.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/resolve.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/scannerc.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/sorter.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/writerc.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/yaml.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/yamlh.go create mode 100644 ihub/vendor/gopkg.in/yaml.v3/yamlprivateh.go create mode 100644 ihub/vendor/modules.txt diff --git a/ihub/vendor/github.com/bytedance/sonic/.gitignore b/ihub/vendor/github.com/bytedance/sonic/.gitignore new file mode 100644 index 0000000..0d88447 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/.gitignore @@ -0,0 +1,52 @@ +*.o +*.swp +*.swm +*.swn +*.a +*.so +_obj +_test +*.[568vq] +[568vq].out +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* +_testmain.go +*.exe +*.exe~ +*.test +*.prof +*.rar +*.zip +*.gz +*.psd +*.bmd +*.cfg +*.pptx +*.log +*nohup.out +*settings.pyc +*.sublime-project +*.sublime-workspace +.DS_Store +/.idea/ +/.vscode/ +/output/ +/vendor/ +/Gopkg.lock +/Gopkg.toml +coverage.html +coverage.out +coverage.xml +junit.xml +*.profile +*.svg +*.out +ast/test.out +ast/bench.sh + +!testdata/*.json.gz +fuzz/testdata +*__debug_bin \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/.gitmodules b/ihub/vendor/github.com/bytedance/sonic/.gitmodules new file mode 100644 index 0000000..b8d11c9 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tools/asm2asm"] + path = tools/asm2asm + url = https://github.com/chenzhuoyu/asm2asm diff --git a/ihub/vendor/github.com/bytedance/sonic/.licenserc.yaml b/ihub/vendor/github.com/bytedance/sonic/.licenserc.yaml new file mode 100644 index 0000000..1cb993e --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/.licenserc.yaml @@ -0,0 +1,24 @@ +header: + license: + spdx-id: Apache-2.0 + copyright-owner: ByteDance Inc. + + paths: + - '**/*.go' + - '**/*.s' + + paths-ignore: + - 'ast/asm.s' # empty file + - 'decoder/asm.s' # empty file + - 'encoder/asm.s' # empty file + - 'internal/caching/asm.s' # empty file + - 'internal/jit/asm.s' # empty file + - 'internal/native/avx/native_amd64.s' # auto-generated by asm2asm + - 'internal/native/avx/native_subr_amd64.go' # auto-generated by asm2asm + - 'internal/native/avx2/native_amd64.s' # auto-generated by asm2asm + - 'internal/native/avx2/native_subr_amd64.go' # auto-generated by asm2asm + - 'internal/resolver/asm.s' # empty file + - 'internal/rt/asm.s' # empty file + - 'internal/loader/asm.s' # empty file + + comment: on-failure \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/CODE_OF_CONDUCT.md b/ihub/vendor/github.com/bytedance/sonic/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..8505feb --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +wudi.daniel@bytedance.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/ihub/vendor/github.com/bytedance/sonic/CONTRIBUTING.md b/ihub/vendor/github.com/bytedance/sonic/CONTRIBUTING.md new file mode 100644 index 0000000..7f63c66 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/CONTRIBUTING.md @@ -0,0 +1,63 @@ +# How to Contribute + +## Your First Pull Request +We use GitHub for our codebase. You can start by reading [How To Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests). + +## Without Semantic Versioning +We keep the stable code in branch `main` like `golang.org/x`. Development base on branch `develop`. We promise the **Forward Compatibility** by adding new package directory with suffix `v2/v3` when code has break changes. + +## Branch Organization +We use [git-flow](https://nvie.com/posts/a-successful-git-branching-model/) as our branch organization, as known as [FDD](https://en.wikipedia.org/wiki/Feature-driven_development) + + +## Bugs +### 1. How to Find Known Issues +We are using [Github Issues](https://github.com/bytedance/sonic/issues) for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn’t already exist. + +### 2. Reporting New Issues +Providing a reduced test code is a recommended way for reporting issues. Then can be placed in: +- Just in issues +- [Golang Playground](https://play.golang.org/) + +### 3. Security Bugs +Please do not report the safe disclosure of bugs to public issues. Contact us by [Support Email](mailto:sonic@bytedance.com) + +## How to Get in Touch +- [Email](mailto:wudi.daniel@bytedance.com) + +## Submit a Pull Request +Before you submit your Pull Request (PR) consider the following guidelines: +1. Search [GitHub](https://github.com/bytedance/sonic/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate existing efforts. +2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add. Discussing the design upfront helps to ensure that we're ready to accept your work. +3. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the bytedance/sonic repo. +4. In your forked repository, make your changes in a new git branch: + ``` + git checkout -b bugfix/security_bug develop + ``` +5. Create your patch, including appropriate test cases. +6. Follow our [Style Guides](#code-style-guides). +7. Commit your changes using a descriptive commit message that follows [AngularJS Git Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit). + Adherence to these conventions is necessary because release notes will be automatically generated from these messages. +8. Push your branch to GitHub: + ``` + git push origin bugfix/security_bug + ``` +9. In GitHub, send a pull request to `sonic:main` + +Note: you must use one of `optimize/feature/bugfix/doc/ci/test/refactor` following a slash(`/`) as the branch prefix. + +Your pr title and commit message should follow https://www.conventionalcommits.org/. + +## Contribution Prerequisites +- Our development environment keeps up with [Go Official](https://golang.org/project/). +- You need fully checking with lint tools before submit your pull request. [gofmt](https://golang.org/pkg/cmd/gofmt/) & [golangci-lint](https://github.com/golangci/golangci-lint) +- You are familiar with [Github](https://github.com) +- Maybe you need familiar with [Actions](https://github.com/features/actions)(our default workflow tool). + +## Code Style Guides +See [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments). + +Good resources: +- [Effective Go](https://golang.org/doc/effective_go) +- [Pingcap General advice](https://pingcap.github.io/style-guide/general.html) +- [Uber Go Style Guide](https://github.com/uber-go/guide/blob/master/style.md) diff --git a/ihub/vendor/github.com/bytedance/sonic/CREDITS b/ihub/vendor/github.com/bytedance/sonic/CREDITS new file mode 100644 index 0000000..e69de29 diff --git a/ihub/vendor/github.com/bytedance/sonic/INTRODUCTION.md b/ihub/vendor/github.com/bytedance/sonic/INTRODUCTION.md new file mode 100644 index 0000000..6b42118 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/INTRODUCTION.md @@ -0,0 +1,48 @@ +# Introduction to Sonic +## Background +According to the overall profiling of production services in Bytedance, we found that the overhead of JSON serialization and deserialization is unexpectedly high: the total is near to 10% CPU, and the extreme one accounts for more than 40% CPU. Therefore, **the performance of JSON lib is a key issue for the promotion of machine utilization**. + +## Research +We conducted a series of surveys and benchmarks on open-sourced JSON libraries for Golang, but the result is disappointing: **no silver bullet**. First of all, no one can perform at least the top three across various business scenarios. Even the most widely used [json-iterator](https://github.com/json-iterator/go) will severely degrade in generic (no-schema) or big-volume JSON serialization and deserialization. Secondly, compared with other JSON libraries writing in other languages, their speed is generally much slower. For example, [Simdjson-go](https://github.com/minio/simdjson-go) has a 50% reduction in decoding performance compared to [simdjson](https://github.com/simdjson/simdjson). What's more, we barely found JSON libraries which provide API to modify the underlying values. + +Therefore, we decided to **develop a brand-new JSON library with high performance as well as wide applicability**. + +## Thinking +Before starting our design, we need to figure out some questions: + +### Why is Json-iterator faster than Standard Library? +First of all, the **schema-based processing mechanism** used by the standard library is commendable, in which the parser can obtain meta information in advance when scanning, thereby shortening the time of branch selection. However, its original implementation did not make good use of this mechanism, instead, **it spent a lot of time reflecting to obtain meta info of schema**. Meanwhile, The approach of json-iterator is: Interprete structure as field-by-field encoding and decoding functions, and then assembled and cached them, minimizing the performance loss cost by reflection. But does it work once and for all? No. In practical tests, we found that **the deeper and larger the input JSON got, the smaller the gap between json-iterator and other libraries gradually became** - eventually event got surpassed: +![Scalability](introduction-1.png) + +The reason is that **this implementation transforms into a large number of interface encapsulations and function calls**, followed by function-call losses: +1. **Calling interface involves dynamic addressing of itab** +2. **Assembly functions cannot be inlined**, while Golang's function-call performance is poor (no parameter-passing-by-register) + +#### Is there a way to avoid the function-call overhead of dynamic assembly? +The first thing we thought about was code generation like [easyjson](https://github.com/mailru/easyjson). But it comes with **schema dependency and convenience losses**. To achieve a real drop-in replacement of the standard library, we turned to another technology - **[JIT](https://en.wikipedia.org/wiki/Jit) (just-in-time compiling)**. Because the compiled codec function is an integrated function, which can greatly reduce function calls while ensuring flexibility. + +### Why is Simdjson-go not fast enough? +[SIMD](https://en.wikipedia.org/wiki/SIMD) (Single-Instruction-Multi-Data) is a special set of CPU instructions for the parallel processing of vectorized data. At present, it is supported by most CPUs and widely used in image processing and big data computing. Undoubtedly, SIMD is useful in JSON processing (itoa, char-search, and so on are all suitable scenarios). We can see that simdjson-go is very competitive in large JSON scenarios (>100KB). However, for some extremely small or irregular character strings, **the extra load operation required by SIMD will lead to performance degradation**. Therefore, we need to dedicate ourselves to branch predicting and decide which scenarios should use SIMD and which should not (for example, the string length is less than 16 bytes). + +The second problem comes from the Go compiler itself. In order to ensure the compilation speed, **Golang does very little optimization work during the compilation phase** and cannot directly use compiler backends such as [LLVM](https://en.wikipedia.org/wiki/LLVM) (Low-Level Virtual Machine) for optimization. + +So, **can some crucial calculation functions be written in another language with higher execution efficiency**? +C/Clang is an ideal compilation tool (internal integration LLVM). But the key is how to embed the optimized assembly into Golang. + +### How to use Gjson well? +We also found that [gjson](https://github.com/tidwall/gjson) has a huge advantage in single-key lookup scenarios. This is because its lookup is implemented by a **lazy-load mechanism**, which subtlely skips passing-by values and effectively reduces a lot of unnecessary parsing. Practical application has proved that making good use of this feature in product can indeed bring benefits. But when it comes to multi-key lookup, Gjson does worse event than std, which is a side effect of its skipping mechanism - **searching for the same path leads to repeated parsing** (skip is also a lightweight parsing). Therefore, the accurate adaptation of practical scenarios is the key. + +## Design +Based on the above questions, our design is easy to implement: + +1. Aiming at the function-call overhead cost by the codec dynamic-assembly, **`JIT` tech is used to assemble opcodes (asm) corresponding to the schema at runtime**, which is finally cached into the off-heap memory in the form of Golang functions. +2. For practical scenarios where big data and small data coexist, we **use pre-conditional judgment** (string size, floating precision, etc.) **to combine `SIMD` with scalar instructions** to achieve the best adaptation. +3. As for insufficiency in compiling optimization of go language, we decided to **use `C/Clang` to write and compile core computational functions**, and **developed a set of [asm2asm](https://github.com/chenzhuoyu/asm2asm) tools to translate the fully optimized x86 assembly into plan9** and finally load it into Golang runtime. +4. Giving the big speed gap between parsing and skipping, the **`lazy-load` mechanism** is certainly used in our AST parser, but in **a more adaptive and efficient way to reduce the overhead of multiple-key queries**. +![design](introduction-2.png) + +In detail, we conducted some further optimization: +1. Since the native-asm functions cannot be inlined in Golang, we found that its cost even exceeded the improvement brought by the optimization of the C compiler. So we reimplemented a set of lightweight function-calls in JIT: + - `Global-function-table + static offset` for calling instruction + - **Pass parameters using registers** +2. `Sync.Map` was used to cache the codecs at first, but for our **quasi-static** (read far more than write), **fewer elements** (usually no more than a few dozen) scenarios, its performance is not optimal, so we reimplement a high-performance and concurrent-safe cache with `open-addressing-hash + RCU` tech. \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/LICENSE b/ihub/vendor/github.com/bytedance/sonic/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/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/ihub/vendor/github.com/bytedance/sonic/Makefile b/ihub/vendor/github.com/bytedance/sonic/Makefile new file mode 100644 index 0000000..8cc0acf --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/Makefile @@ -0,0 +1,112 @@ +# +# Copyright 2021 ByteDance Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +ARCH := avx avx2 sse +TMP_DIR := output +OUT_DIR := internal/native +SRC_FILE := native/native.c + +CPU_avx := amd64 +CPU_avx2 := amd64 +CPU_sse := amd64 + +TMPL_avx := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64 +TMPL_avx2 := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64 +TMPL_sse := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64 + +CFLAGS_avx := -msse -mno-sse4 -mavx -mpclmul -mno-avx2 -DUSE_AVX=1 -DUSE_AVX2=0 +CFLAGS_avx2 := -msse -mno-sse4 -mavx -mpclmul -mavx2 -DUSE_AVX=1 -DUSE_AVX2=1 +CFLAGS_sse := -msse -mno-sse4 -mno-avx -mno-avx2 -mpclmul + +CC_amd64 := clang +ASM2ASM_amd64 := tools/asm2asm/asm2asm.py + +CFLAGS := -mno-red-zone +CFLAGS += -target x86_64-apple-macos11 +CFLAGS += -fno-asynchronous-unwind-tables +CFLAGS += -fno-builtin +CFLAGS += -fno-exceptions +CFLAGS += -fno-rtti +CFLAGS += -fno-stack-protector +CFLAGS += -nostdlib +CFLAGS += -O3 +CFLAGS += -Wall -Werror + +NATIVE_SRC := $(wildcard native/*.h) +NATIVE_SRC += $(wildcard native/*.c) + +.PHONY: all clean ${ARCH} + +define build_tmpl + $(eval @arch := $(1)) + $(eval @tmpl := $(2)) + $(eval @dest := $(3)) + +${@dest}: ${@tmpl} + mkdir -p $(dir ${@dest}) + echo '// Code generated by Makefile, DO NOT EDIT.' > ${@dest} + echo >> ${@dest} + sed -e 's/{{PACKAGE}}/${@arch}/g' ${@tmpl} >> ${@dest} +endef + +define build_arch + $(eval @cpu := $(value CPU_$(1))) + $(eval @deps := $(foreach tmpl,$(value TMPL_$(1)),${OUT_DIR}/$(1)/${tmpl}.go)) + $(eval @asmin := ${TMP_DIR}/$(1)/native.s) + $(eval @asmout := ${OUT_DIR}/$(1)/native_${@cpu}.s) + $(eval @stubin := ${OUT_DIR}/native_${@cpu}.tmpl) + $(eval @stubout := ${OUT_DIR}/$(1)/native_${@cpu}.go) + +$(1): ${@asmout} ${@deps} + +${@asmout}: ${@stubout} ${NATIVE_SRC} + mkdir -p ${TMP_DIR}/$(1) + $${CC_${@cpu}} $${CFLAGS} $${CFLAGS_$(1)} -S -o ${TMP_DIR}/$(1)/native.s ${SRC_FILE} + python3 $${ASM2ASM_${@cpu}} ${@asmout} ${TMP_DIR}/$(1)/native.s + asmfmt -w ${@asmout} + +$(eval $(call \ + build_tmpl, \ + $(1), \ + ${@stubin}, \ + ${@stubout} \ +)) + +$(foreach \ + tmpl, \ + $(value TMPL_$(1)), \ + $(eval $(call \ + build_tmpl, \ + $(1), \ + ${OUT_DIR}/${tmpl}.tmpl, \ + ${OUT_DIR}/$(1)/${tmpl}.go \ + )) \ +) +endef + +all: ${ARCH} + +clean: + for arch in ${ARCH}; do \ + rm -vfr ${TMP_DIR}/$${arch}; \ + rm -vfr ${OUT_DIR}/$${arch}; \ + done + +$(foreach \ + arch, \ + ${ARCH}, \ + $(eval $(call build_arch,${arch})) \ +) diff --git a/ihub/vendor/github.com/bytedance/sonic/README.md b/ihub/vendor/github.com/bytedance/sonic/README.md new file mode 100644 index 0000000..9cc42c4 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/README.md @@ -0,0 +1,359 @@ +# Sonic + +A blazingly fast JSON serializing & deserializing library, accelerated by JIT (just-in-time compiling) and SIMD (single-instruction-multiple-data). + +## Requirement +- Go 1.15~1.20 +- Linux/MacOS/Windows +- Amd64 ARCH + +## Features +- Runtime object binding without code generation +- Complete APIs for JSON value manipulation +- Fast, fast, fast! + +## Benchmarks +For **all sizes** of json and **all scenarios** of usage, **Sonic performs best**. +- [Medium](https://github.com/bytedance/sonic/blob/main/decoder/testdata_test.go#L19) (13KB, 300+ key, 6 layers) +```powershell +goversion: 1.17.1 +goos: darwin +goarch: amd64 +cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz +BenchmarkEncoder_Generic_Sonic-16 32393 ns/op 402.40 MB/s 11965 B/op 4 allocs/op +BenchmarkEncoder_Generic_Sonic_Fast-16 21668 ns/op 601.57 MB/s 10940 B/op 4 allocs/op +BenchmarkEncoder_Generic_JsonIter-16 42168 ns/op 309.12 MB/s 14345 B/op 115 allocs/op +BenchmarkEncoder_Generic_GoJson-16 65189 ns/op 199.96 MB/s 23261 B/op 16 allocs/op +BenchmarkEncoder_Generic_StdLib-16 106322 ns/op 122.60 MB/s 49136 B/op 789 allocs/op +BenchmarkEncoder_Binding_Sonic-16 6269 ns/op 2079.26 MB/s 14173 B/op 4 allocs/op +BenchmarkEncoder_Binding_Sonic_Fast-16 5281 ns/op 2468.16 MB/s 12322 B/op 4 allocs/op +BenchmarkEncoder_Binding_JsonIter-16 20056 ns/op 649.93 MB/s 9488 B/op 2 allocs/op +BenchmarkEncoder_Binding_GoJson-16 8311 ns/op 1568.32 MB/s 9481 B/op 1 allocs/op +BenchmarkEncoder_Binding_StdLib-16 16448 ns/op 792.52 MB/s 9479 B/op 1 allocs/op +BenchmarkEncoder_Parallel_Generic_Sonic-16 6681 ns/op 1950.93 MB/s 12738 B/op 4 allocs/op +BenchmarkEncoder_Parallel_Generic_Sonic_Fast-16 4179 ns/op 3118.99 MB/s 10757 B/op 4 allocs/op +BenchmarkEncoder_Parallel_Generic_JsonIter-16 9861 ns/op 1321.84 MB/s 14362 B/op 115 allocs/op +BenchmarkEncoder_Parallel_Generic_GoJson-16 18850 ns/op 691.52 MB/s 23278 B/op 16 allocs/op +BenchmarkEncoder_Parallel_Generic_StdLib-16 45902 ns/op 283.97 MB/s 49174 B/op 789 allocs/op +BenchmarkEncoder_Parallel_Binding_Sonic-16 1480 ns/op 8810.09 MB/s 13049 B/op 4 allocs/op +BenchmarkEncoder_Parallel_Binding_Sonic_Fast-16 1209 ns/op 10785.23 MB/s 11546 B/op 4 allocs/op +BenchmarkEncoder_Parallel_Binding_JsonIter-16 6170 ns/op 2112.58 MB/s 9504 B/op 2 allocs/op +BenchmarkEncoder_Parallel_Binding_GoJson-16 3321 ns/op 3925.52 MB/s 9496 B/op 1 allocs/op +BenchmarkEncoder_Parallel_Binding_StdLib-16 3739 ns/op 3486.49 MB/s 9480 B/op 1 allocs/op + +BenchmarkDecoder_Generic_Sonic-16 66812 ns/op 195.10 MB/s 57602 B/op 723 allocs/op +BenchmarkDecoder_Generic_Sonic_Fast-16 54523 ns/op 239.07 MB/s 49786 B/op 313 allocs/op +BenchmarkDecoder_Generic_StdLib-16 124260 ns/op 104.90 MB/s 50869 B/op 772 allocs/op +BenchmarkDecoder_Generic_JsonIter-16 91274 ns/op 142.81 MB/s 55782 B/op 1068 allocs/op +BenchmarkDecoder_Generic_GoJson-16 88569 ns/op 147.17 MB/s 66367 B/op 973 allocs/op +BenchmarkDecoder_Binding_Sonic-16 32557 ns/op 400.38 MB/s 28302 B/op 137 allocs/op +BenchmarkDecoder_Binding_Sonic_Fast-16 28649 ns/op 455.00 MB/s 24999 B/op 34 allocs/op +BenchmarkDecoder_Binding_StdLib-16 111437 ns/op 116.97 MB/s 10576 B/op 208 allocs/op +BenchmarkDecoder_Binding_JsonIter-16 35090 ns/op 371.48 MB/s 14673 B/op 385 allocs/op +BenchmarkDecoder_Binding_GoJson-16 28738 ns/op 453.59 MB/s 22039 B/op 49 allocs/op +BenchmarkDecoder_Parallel_Generic_Sonic-16 12321 ns/op 1057.91 MB/s 57233 B/op 723 allocs/op +BenchmarkDecoder_Parallel_Generic_Sonic_Fast-16 10644 ns/op 1224.64 MB/s 49362 B/op 313 allocs/op +BenchmarkDecoder_Parallel_Generic_StdLib-16 57587 ns/op 226.35 MB/s 50874 B/op 772 allocs/op +BenchmarkDecoder_Parallel_Generic_JsonIter-16 38666 ns/op 337.12 MB/s 55789 B/op 1068 allocs/op +BenchmarkDecoder_Parallel_Generic_GoJson-16 30259 ns/op 430.79 MB/s 66370 B/op 974 allocs/op +BenchmarkDecoder_Parallel_Binding_Sonic-16 5965 ns/op 2185.28 MB/s 27747 B/op 137 allocs/op +BenchmarkDecoder_Parallel_Binding_Sonic_Fast-16 5170 ns/op 2521.31 MB/s 24715 B/op 34 allocs/op +BenchmarkDecoder_Parallel_Binding_StdLib-16 27582 ns/op 472.58 MB/s 10576 B/op 208 allocs/op +BenchmarkDecoder_Parallel_Binding_JsonIter-16 13571 ns/op 960.51 MB/s 14685 B/op 385 allocs/op +BenchmarkDecoder_Parallel_Binding_GoJson-16 10031 ns/op 1299.51 MB/s 22111 B/op 49 allocs/op + +BenchmarkGetOne_Sonic-16 3276 ns/op 3975.78 MB/s 24 B/op 1 allocs/op +BenchmarkGetOne_Gjson-16 9431 ns/op 1380.81 MB/s 0 B/op 0 allocs/op +BenchmarkGetOne_Jsoniter-16 51178 ns/op 254.46 MB/s 27936 B/op 647 allocs/op +BenchmarkGetOne_Parallel_Sonic-16 216.7 ns/op 60098.95 MB/s 24 B/op 1 allocs/op +BenchmarkGetOne_Parallel_Gjson-16 1076 ns/op 12098.62 MB/s 0 B/op 0 allocs/op +BenchmarkGetOne_Parallel_Jsoniter-16 17741 ns/op 734.06 MB/s 27945 B/op 647 allocs/op +BenchmarkSetOne_Sonic-16 9571 ns/op 1360.61 MB/s 1584 B/op 17 allocs/op +BenchmarkSetOne_Sjson-16 36456 ns/op 357.22 MB/s 52180 B/op 9 allocs/op +BenchmarkSetOne_Jsoniter-16 79475 ns/op 163.86 MB/s 45862 B/op 964 allocs/op +BenchmarkSetOne_Parallel_Sonic-16 850.9 ns/op 15305.31 MB/s 1584 B/op 17 allocs/op +BenchmarkSetOne_Parallel_Sjson-16 18194 ns/op 715.77 MB/s 52247 B/op 9 allocs/op +BenchmarkSetOne_Parallel_Jsoniter-16 33560 ns/op 388.05 MB/s 45892 B/op 964 allocs/op +``` +- [Small](https://github.com/bytedance/sonic/blob/main/testdata/small.go) (400B, 11 keys, 3 layers) +![small benchmarks](bench-small.png) +- [Large](https://github.com/bytedance/sonic/blob/main/testdata/twitter.json) (635KB, 10000+ key, 6 layers) +![large benchmarks](bench-large.png) + +See [bench.sh](https://github.com/bytedance/sonic/blob/main/bench.sh) for benchmark codes. + +## How it works +See [INTRODUCTION.md](INTRODUCTION.md). + +## Usage + +### Marshal/Unmarshal + +Default behaviors are mostly consistent with `encoding/json`, except HTML escaping form (see [Escape HTML](https://github.com/bytedance/sonic/blob/main/README.md#escape-html)) and `SortKeys` feature (optional support see [Sort Keys](https://github.com/bytedance/sonic/blob/main/README.md#sort-keys)) that is **NOT** in conformity to [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259). + ```go +import "github.com/bytedance/sonic" + +var data YourSchema +// Marshal +output, err := sonic.Marshal(&data) +// Unmarshal +err := sonic.Unmarshal(output, &data) + ``` + +### Streaming IO +Sonic supports decoding json from `io.Reader` or encoding objects into `io.`Writer`, aims at handling multiple values as well as reducing memory consumption. +- encoder +```go +import "github.com/bytedance/sonic/encoder" + +var o1 = map[string]interface{}{ + "a": "b", +} +var o2 = 1 +var w = bytes.NewBuffer(nil) +var enc = encoder.NewStreamEncoder(w) +enc.Encode(o1) +enc.Encode(o2) +println(w.String()) // "{"a":"b"}\n1" +``` +- decoder +```go +import "github.com/bytedance/sonic/decoder" + +var o = map[string]interface{}{} +var r = strings.NewReader(`{"a":"b"}{"1":"2"}`) +var dec = decoder.NewStreamDecoder(r) +dec.Decode(&o) +dec.Decode(&o) +fmt.Printf("%+v", o) // map[1:2 a:b] +``` + +### Use Number/Use Int64 + ```go +import "github.com/bytedance/sonic/decoder" + +var input = `1` +var data interface{} + +// default float64 +dc := decoder.NewDecoder(input) +dc.Decode(&data) // data == float64(1) +// use json.Number +dc = decoder.NewDecoder(input) +dc.UseNumber() +dc.Decode(&data) // data == json.Number("1") +// use int64 +dc = decoder.NewDecoder(input) +dc.UseInt64() +dc.Decode(&data) // data == int64(1) + +root, err := sonic.GetFromString(input) +// Get json.Number +jn := root.Number() +jm := root.InterfaceUseNumber().(json.Number) // jn == jm +// Get float64 +fn := root.Float64() +fm := root.Interface().(float64) // jn == jm + ``` + +### Sort Keys +On account of the performance loss from sorting (roughly 10%), sonic doesn't enable this feature by default. If your component depends on it to work (like [zstd](https://github.com/facebook/zstd)), Use it like this: +```go +import "github.com/bytedance/sonic" +import "github.com/bytedance/sonic/encoder" + +// Binding map only +m := map[string]interface{}{} +v, err := encoder.Encode(m, encoder.SortMapKeys) + +// Or ast.Node.SortKeys() before marshal +var root := sonic.Get(JSON) +err := root.SortKeys() +``` +### Escape HTML +On account of the performance loss (roughly 15%), sonic doesn't enable this feature by default. You can use `encoder.EscapeHTML` option to open this feature (align with `encoding/json.HTMLEscape`). +```go +import "github.com/bytedance/sonic" + +v := map[string]string{"&&":"<>"} +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. + +### Print Error +If there invalid syntax in input JSON, sonic will return `decoder.SyntaxError`, which supports pretty-printing of error position +```go +import "github.com/bytedance/sonic" +import "github.com/bytedance/sonic/decoder" + +var data interface{} +err := sonic.UnmarshalString("[[[}]]", &data) +if err != nil { + /* One line by default */ + println(e.Error()) // "Syntax error at index 3: invalid char\n\n\t[[[}]]\n\t...^..\n" + /* Pretty print */ + if e, ok := err.(decoder.SyntaxError); ok { + /*Syntax error at index 3: invalid char + + [[[}]] + ...^.. + */ + print(e.Description()) + } else if me, ok := err.(*decoder.MismatchTypeError); ok { + // decoder.MismatchTypeError is new to Sonic v1.6.0 + print(me.Description()) + } +} +``` + +#### Mismatched Types [Sonic v1.6.0] +If there a **mismatch-typed** value for a given key, sonic will report `decoder.MismatchTypeError` (if there are many, report the last one), but still skip wrong the value and keep decoding next JSON. +```go +import "github.com/bytedance/sonic" +import "github.com/bytedance/sonic/decoder" + +var data = struct{ + A int + B int +}{} +err := UnmarshalString(`{"A":"1","B":1}`, &data) +println(err.Error()) // Mismatch type int with value string "at index 5: mismatched type with value\n\n\t{\"A\":\"1\",\"B\":1}\n\t.....^.........\n" +fmt.Printf("%+v", data) // {A:0 B:1} +``` +### Ast.Node +Sonic/ast.Node is a completely self-contained AST for JSON. It implements serialization and deserialization both and provides robust APIs for obtaining and modification of generic data. +#### Get/Index +Search partial JSON by given paths, which must be non-negative integer or string, or nil +```go +import "github.com/bytedance/sonic" + +input := []byte(`{"key1":[{},{"key2":{"key3":[1,2,3]}}]}`) + +// no path, returns entire json +root, err := sonic.Get(input) +raw := root.Raw() // == string(input) + +// multiple paths +root, err := sonic.Get(input, "key1", 1, "key2") +sub := root.Get("key3").Index(2).Int64() // == 3 +``` +**Tip**: since `Index()` uses offset to locate data, which is much faster than scanning like `Get()`, we suggest you use it as much as possible. And sonic also provides another API `IndexOrGet()` to underlying use offset as well as ensure the key is matched. + +#### Set/Unset +Modify the json content by Set()/Unset() +```go +import "github.com/bytedance/sonic" + +// Set +exist, err := root.Set("key4", NewBool(true)) // exist == false +alias1 := root.Get("key4") +println(alias1.Valid()) // true +alias2 := root.Index(1) +println(alias1 == alias2) // true + +// Unset +exist, err := root.UnsetByIndex(1) // exist == true +println(root.Get("key4").Check()) // "value not exist" +``` + +#### Serialize +To encode `ast.Node` as json, use `MarshalJson()` or `json.Marshal()` (MUST pass the node's pointer) +```go +import ( + "encoding/json" + "github.com/bytedance/sonic" +) + +buf, err := root.MarshalJson() +println(string(buf)) // {"key1":[{},{"key2":{"key3":[1,2,3]}}]} +exp, err := json.Marshal(&root) // WARN: use pointer +println(string(buf) == string(exp)) // true +``` + +#### APIs +- validation: `Check()`, `Error()`, `Valid()`, `Exist()` +- searching: `Index()`, `Get()`, `IndexPair()`, `IndexOrGet()`, `GetByPath()` +- go-type casting: `Int64()`, `Float64()`, `String()`, `Number()`, `Bool()`, `Map[UseNumber|UseNode]()`, `Array[UseNumber|UseNode]()`, `Interface[UseNumber|UseNode]()` +- go-type packing: `NewRaw()`, `NewNumber()`, `NewNull()`, `NewBool()`, `NewString()`, `NewObject()`, `NewArray()` +- iteration: `Values()`, `Properties()`, `ForEach()`, `SortKeys()` +- modification: `Set()`, `SetByIndex()`, `Add()` + +## Compatibility +Sonic **DOES NOT** ensure to support all environments, due to the difficulty of developing high-performance codes. For developers who use sonic to build their applications in different environments, we have the following suggestions: + +- Developing on **Mac M1**: Make sure you have Rosetta 2 installed on your machine, and set `GOARCH=amd64` when building your application. Rosetta 2 can automatically translate x86 binaries to arm64 binaries and run x86 applications on Mac M1. +- Developing on **Linux arm64**: You can install qemu and use the `qemu-x86_64 -cpu max` command to convert x86 binaries to amr64 binaries for applications built with sonic. The qemu can achieve a similar transfer effect to Rosetta 2 on Mac M1. + +For developers who want to use sonic on Linux arm64 without qemu, or those who want to handle JSON strictly consistent with `encoding/json`, we provide some compatible APIs as `sonic.API` +- `ConfigDefault`: the sonic's default config (`EscapeHTML=false`,`SortKeys=false`...) to run on sonic-supporting environment. It will fall back to `encoding/json` with the corresponding config, and some options like `SortKeys=false` will be invalid. +- `ConfigStd`: the std-compatible config (`EscapeHTML=true`,`SortKeys=true`...) to run on sonic-supporting environment. It will fall back to `encoding/json`. +- `ConfigFastest`: the fastest config (`NoQuoteTextMarshaler=true`) to run on sonic-supporting environment. It will fall back to `encoding/json` with the corresponding config, and some options will be invalid. + +## Tips + +### Pretouch +Since Sonic uses [golang-asm](https://github.com/twitchyliquid64/golang-asm) as a JIT assembler, which is NOT very suitable for runtime compiling, first-hit running of a huge schema may cause request-timeout or even process-OOM. For better stability, we advise **using `Pretouch()` for huge-schema or compact-memory applications** before `Marshal()/Unmarshal()`. +```go +import ( + "reflect" + "github.com/bytedance/sonic" + "github.com/bytedance/sonic/option" +) + +func init() { + var v HugeStruct + + // For most large types (nesting depth <= option.DefaultMaxInlineDepth) + err := sonic.Pretouch(reflect.TypeOf(v)) + + // with more CompileOption... + err := sonic.Pretouch(reflect.TypeOf(v), + // If the type is too deep nesting (nesting depth > option.DefaultMaxInlineDepth), + // you can set compile recursive loops in Pretouch for better stability in JIT. + option.WithCompileRecursiveDepth(loop), + // For a large nested struct, try to set a smaller depth to reduce compiling time. + option.WithCompileMaxInlineDepth(depth), + ) +} +``` + +### Copy string +When decoding **string values without any escaped characters**, sonic references them from the origin JSON buffer instead of mallocing a new buffer to copy. This helps a lot for CPU performance but may leave the whole JSON buffer in memory as long as the decoded objects are being used. In practice, we found the extra memory introduced by referring JSON buffer is usually 20% ~ 80% of decoded objects. Once an application holds these objects for a long time (for example, cache the decoded objects for reusing), its in-use memory on the server may go up. We provide the option `decoder.CopyString()` for users to choose not to reference the JSON buffer, which may cause a decline in CPU performance to some degree. + +### Pass string or []byte? +For alignment to `encoding/json`, we provide API to pass `[]byte` as an argument, but the string-to-bytes copy is conducted at the same time considering safety, which may lose performance when the origin JSON is huge. Therefore, you can use `UnmarshalString()` and `GetFromString()` to pass a string, as long as your origin data is a string or **nocopy-cast** is safe for your []byte. We also provide API `MarshalString()` for convenient **nocopy-cast** of encoded JSON []byte, which is safe since sonic's output bytes is always duplicated and unique. + +### Accelerate `encoding.TextMarshaler` +To ensure data security, sonic.Encoder quotes and escapes string values from `encoding.TextMarshaler` interfaces by default, which may degrade performance much if most of your data is in form of them. We provide `encoder.NoQuoteTextMarshaler` to skip these operations, which means you **MUST** ensure their output string escaped and quoted following [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259). + + +### Better performance for generic data +In **fully-parsed** scenario, `Unmarshal()` performs better than `Get()`+`Node.Interface()`. But if you only have a part of the schema for specific json, you can combine `Get()` and `Unmarshal()` together: +```go +import "github.com/bytedance/sonic" + +node, err := sonic.GetFromString(_TwitterJson, "statuses", 3, "user") +var user User // your partial schema... +err = sonic.UnmarshalString(node.Raw(), &user) +``` +Even if you don't have any schema, use `ast.Node` as the container of generic values instead of `map` or `interface`: +```go +import "github.com/bytedance/sonic" + +root, err := sonic.GetFromString(_TwitterJson) +user := root.GetByPath("statuses", 3, "user") // === root.Get("status").Index(3).Get("user") +err = user.Check() + +// err = user.LoadAll() // only call this when you want to use 'user' concurrently... +go someFunc(user) +``` +Why? Because `ast.Node` stores its children using `array`: +- `Array`'s performance is **much better** than `Map` when Inserting (Deserialize) and Scanning (Serialize) data; +- **Hashing** (`map[x]`) is not as efficient as **Indexing** (`array[x]`), which `ast.Node` can conduct on **both array and object**; +- Using `Interface()`/`Map()` means Sonic must parse all the underlying values, while `ast.Node` can parse them **on demand**. + +**CAUTION:** `ast.Node` **DOESN'T** ensure concurrent security directly, due to its **lazy-load** design. However, you can call `Node.Load()`/`Node.LoadAll()` to achieve that, which may bring performance reduction while it still works faster than converting to `map` or `interface{}` + +## Community +Sonic is a subproject of [CloudWeGo](https://www.cloudwego.io/). We are committed to building a cloud native ecosystem. diff --git a/ihub/vendor/github.com/bytedance/sonic/api.go b/ihub/vendor/github.com/bytedance/sonic/api.go new file mode 100644 index 0000000..a2bc67e --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/api.go @@ -0,0 +1,185 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sonic + +import ( + `io` + + `github.com/bytedance/sonic/ast` +) + +// Config is a combination of sonic/encoder.Options and sonic/decoder.Options +type Config struct { + // EscapeHTML indicates encoder to escape all HTML characters + // after serializing into JSON (see https://pkg.go.dev/encoding/json#HTMLEscape). + // WARNING: This hurts performance A LOT, USE WITH CARE. + EscapeHTML bool + + // SortMapKeys indicates encoder that the keys of a map needs to be sorted + // before serializing into JSON. + // WARNING: This hurts performance A LOT, USE WITH CARE. + SortMapKeys bool + + // CompactMarshaler indicates encoder that the output JSON from json.Marshaler + // is always compact and needs no validation + CompactMarshaler bool + + // NoQuoteTextMarshaler indicates encoder that the output text from encoding.TextMarshaler + // is always escaped string and needs no quoting + NoQuoteTextMarshaler bool + + // NoNullSliceOrMap indicates encoder that all empty Array or Object are encoded as '[]' or '{}', + // instead of 'null' + NoNullSliceOrMap bool + + // UseInt64 indicates decoder to unmarshal an integer into an interface{} as an + // int64 instead of as a float64. + UseInt64 bool + + // UseNumber indicates decoder to unmarshal a number into an interface{} as a + // json.Number instead of as a float64. + UseNumber bool + + // UseUnicodeErrors indicates decoder to return an error when encounter invalid + // UTF-8 escape sequences. + UseUnicodeErrors bool + + // DisallowUnknownFields indicates decoder to return an error when the destination + // is a struct and the input contains object keys which do not match any + // non-ignored, exported fields in the destination. + DisallowUnknownFields bool + + // 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 + // when unescaped control chars(\u0000-\u001f) in the string value of JSON. + ValidateString bool +} + +var ( + // ConfigDefault is the default config of APIs, aiming at efficiency and safty. + ConfigDefault = Config{}.Froze() + + // ConfigStd is the standard config of APIs, aiming at being compatible with encoding/json. + ConfigStd = Config{ + EscapeHTML : true, + SortMapKeys: true, + CompactMarshaler: true, + CopyString : true, + ValidateString : true, + }.Froze() + + // ConfigFastest is the fastest config of APIs, aiming at speed. + ConfigFastest = Config{ + NoQuoteTextMarshaler: true, + }.Froze() +) + + +// API is a binding of specific config. +// This interface is inspired by github.com/json-iterator/go, +// and has same behaviors under equavilent config. +type API interface { + // MarshalToString returns the JSON encoding string of v + MarshalToString(v interface{}) (string, error) + // Marshal returns the JSON encoding bytes of v. + Marshal(v interface{}) ([]byte, error) + // MarshalIndent returns the JSON encoding bytes with indent and prefix. + MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) + // UnmarshalFromString parses the JSON-encoded bytes and stores the result in the value pointed to by v. + UnmarshalFromString(str string, v interface{}) error + // Unmarshal parses the JSON-encoded string and stores the result in the value pointed to by v. + Unmarshal(data []byte, v interface{}) error + // NewEncoder create a Encoder holding writer + NewEncoder(writer io.Writer) Encoder + // NewDecoder create a Decoder holding reader + NewDecoder(reader io.Reader) Decoder + // Valid validates the JSON-encoded bytes and reportes if it is valid + Valid(data []byte) bool +} + +// Encoder encodes JSON into io.Writer +type Encoder interface { + // Encode writes the JSON encoding of v to the stream, followed by a newline character. + Encode(val interface{}) error + // SetEscapeHTML specifies whether problematic HTML characters + // should be escaped inside JSON quoted strings. + // The default behavior NOT ESCAPE + SetEscapeHTML(on bool) + // SetIndent instructs the encoder to format each subsequent encoded value + // as if indented by the package-level function Indent(dst, src, prefix, indent). + // Calling SetIndent("", "") disables indentation + SetIndent(prefix, indent string) +} + +// Decoder decodes JSON from io.Read +type Decoder interface { + // Decode reads the next JSON-encoded value from its input and stores it in the value pointed to by v. + Decode(val interface{}) error + // Buffered returns a reader of the data remaining in the Decoder's buffer. + // The reader is valid until the next call to Decode. + Buffered() io.Reader + // DisallowUnknownFields causes the Decoder to return an error when the destination is a struct + // and the input contains object keys which do not match any non-ignored, exported fields in the destination. + DisallowUnknownFields() + // More reports whether there is another element in the current array or object being parsed. + More() bool + // UseNumber causes the Decoder to unmarshal a number into an interface{} as a Number instead of as a float64. + UseNumber() +} + +// Marshal returns the JSON encoding bytes of v. +func Marshal(val interface{}) ([]byte, error) { + return ConfigDefault.Marshal(val) +} + +// MarshalString returns the JSON encoding string of v. +func MarshalString(val interface{}) (string, error) { + return ConfigDefault.MarshalToString(val) +} + +// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. +// NOTICE: This API copies given buffer by default, +// if you want to pass JSON more efficiently, use UnmarshalString instead. +func Unmarshal(buf []byte, val interface{}) error { + return ConfigDefault.Unmarshal(buf, val) +} + +// UnmarshalString is like Unmarshal, except buf is a string. +func UnmarshalString(buf string, val interface{}) error { + return ConfigDefault.UnmarshalFromString(buf, val) +} + +// Get searches the given path from json, +// and returns its representing ast.Node. +// +// Each path arg must be integer or string: +// - Integer means searching current node as array +// - String means searching current node as object +// +// Note, the api expects the json is well-formed at least, +// otherwise it may return unexpected result. +func Get(src []byte, path ...interface{}) (ast.Node, error) { + return GetFromString(string(src), path...) +} + +// GetFromString is same with Get except src is string, +// which can reduce unnecessary memory copy. +func GetFromString(src string, path ...interface{}) (ast.Node, error) { + return ast.NewSearcher(src).GetByPath(path...) +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/api_amd64.go b/ihub/vendor/github.com/bytedance/sonic/ast/api_amd64.go new file mode 100644 index 0000000..6b3458a --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/api_amd64.go @@ -0,0 +1,126 @@ +// +build amd64,go1.15,!go1.21 + + +package ast + +import ( + `runtime` + `unsafe` + + `github.com/bytedance/sonic/encoder` + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` + uq `github.com/bytedance/sonic/unquote` + `github.com/chenzhuoyu/base64x` +) + +var typeByte = rt.UnpackEface(byte(0)).Type + +func quote(buf *[]byte, val string) { + *buf = append(*buf, '"') + if len(val) == 0 { + *buf = append(*buf, '"') + } + + sp := rt.IndexChar(val, 0) + nb := len(val) + b := (*rt.GoSlice)(unsafe.Pointer(buf)) + + // input buffer + for nb > 0 { + // output buffer + dp := unsafe.Pointer(uintptr(b.Ptr) + uintptr(b.Len)) + dn := b.Cap - b.Len + // call native.Quote, dn is byte count it outputs + ret := native.Quote(sp, nb, dp, &dn, 0) + // update *buf length + b.Len += dn + + // no need more output + if ret >= 0 { + break + } + + // double buf size + *b = growslice(typeByte, *b, b.Cap*2) + // ret is the complement of consumed input + ret = ^ret + // update input buffer + nb -= ret + sp = unsafe.Pointer(uintptr(sp) + uintptr(ret)) + } + + runtime.KeepAlive(buf) + runtime.KeepAlive(sp) + *buf = append(*buf, '"') +} + +func unquote(src string) (string, types.ParsingError) { + return uq.String(src) +} + +func decodeBase64(src string) ([]byte, error) { + return base64x.StdEncoding.DecodeString(src) +} + +func encodeBase64(src []byte) string { + return base64x.StdEncoding.EncodeToString(src) +} + +func (self *Parser) decodeValue() (val types.JsonState) { + sv := (*rt.GoString)(unsafe.Pointer(&self.s)) + self.p = native.Value(sv.Ptr, sv.Len, self.p, &val, 0) + return +} + +func (self *Parser) skip() (int, types.ParsingError) { + fsm := types.NewStateMachine() + start := native.SkipOne(&self.s, &self.p, fsm, 0) + types.FreeStateMachine(fsm) + + if start < 0 { + return self.p, types.ParsingError(-start) + } + return start, 0 +} + +func (self *Node) encodeInterface(buf *[]byte) error { + //WARN: NOT compatible with json.Encoder + return encoder.EncodeInto(buf, self.packAny(), 0) +} + +func (self *Parser) skipFast() (int, types.ParsingError) { + start := native.SkipOneFast(&self.s, &self.p) + if start < 0 { + return self.p, types.ParsingError(-start) + } + return start, 0 +} + +func (self *Parser) getByPath(path ...interface{}) (int, types.ParsingError) { + start := native.GetByPath(&self.s, &self.p, &path) + runtime.KeepAlive(path) + if start < 0 { + return self.p, types.ParsingError(-start) + } + return start, 0 +} + + +func (self *Searcher) GetByPath(path ...interface{}) (Node, error) { + var err types.ParsingError + var start int + + self.parser.p = 0 + start, err = self.parser.getByPath(path...) + if err != 0 { + return Node{}, self.parser.syntaxError(err) + } + + t := switchRawType(self.parser.s[start]) + if t == _V_NONE { + return Node{}, self.parser.ExportError(err) + } + return newRawNode(self.parser.s[start:self.parser.p], t), nil +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/api_compat.go b/ihub/vendor/github.com/bytedance/sonic/ast/api_compat.go new file mode 100644 index 0000000..642330c --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/api_compat.go @@ -0,0 +1,102 @@ +// +build !amd64 go1.21 + +package ast + +import ( + `encoding/base64` + `encoding/json` + `fmt` + + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` +) + +func quote(buf *[]byte, val string) { + quoteString(buf, val) +} + +func unquote(src string) (string, types.ParsingError) { + sp := rt.IndexChar(src, -1) + out, ok := unquoteBytes(rt.BytesFrom(sp, len(src)+2, len(src)+2)) + if !ok { + return "", types.ERR_INVALID_ESCAPE + } + return rt.Mem2Str(out), 0 +} + + + +func decodeBase64(src string) ([]byte, error) { + return base64.StdEncoding.DecodeString(src) +} + +func encodeBase64(src []byte) string { + return base64.StdEncoding.EncodeToString(src) +} + +func (self *Parser) decodeValue() (val types.JsonState) { + e, v := decodeValue(self.s, self.p) + if e < 0 { + return v + } + self.p = e + return v +} + +func (self *Parser) skip() (int, types.ParsingError) { + e, s := skipValue(self.s, self.p) + if e < 0 { + return self.p, types.ParsingError(-e) + } + self.p = e + return s, 0 +} + +func (self *Parser) skipFast() (int, types.ParsingError) { + return self.skip() +} + +func (self *Node) encodeInterface(buf *[]byte) error { + out, err := json.Marshal(self.packAny()) + if err != nil { + return err + } + *buf = append(*buf, out...) + return nil +} + +func (self *Searcher) GetByPath(path ...interface{}) (Node, error) { + self.parser.p = 0 + + var err types.ParsingError + for _, p := range path { + switch p := p.(type) { + case int: + if err = self.parser.searchIndex(p); err != 0 { + return Node{}, self.parser.ExportError(err) + } + case string: + if err = self.parser.searchKey(p); err != 0 { + return Node{}, self.parser.ExportError(err) + } + default: + panic("path must be either int or string") + } + } + + var start = self.parser.p + if start, err = self.parser.skip(); err != 0 { + return Node{}, self.parser.ExportError(err) + } + ns := len(self.parser.s) + if self.parser.p > ns || start >= ns || start>=self.parser.p { + return Node{}, fmt.Errorf("skip %d char out of json boundary", start) + } + + t := switchRawType(self.parser.s[start]) + if t == _V_NONE { + return Node{}, self.parser.ExportError(err) + } + + return newRawNode(self.parser.s[start:self.parser.p], t), nil +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/asm.s b/ihub/vendor/github.com/bytedance/sonic/ast/asm.s new file mode 100644 index 0000000..e69de29 diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/decode.go b/ihub/vendor/github.com/bytedance/sonic/ast/decode.go new file mode 100644 index 0000000..d54e983 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/decode.go @@ -0,0 +1,430 @@ +package ast + +import ( + `encoding/base64` + `runtime` + `strconv` + `unsafe` + + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` +) + +const _blankCharsMask = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n') + +const ( + bytesNull = "null" + bytesTrue = "true" + bytesFalse = "false" + bytesObject = "{}" + bytesArray = "[]" +) + +func isSpace(c byte) bool { + return (int(1<= se { + return -int(types.ERR_EOF) + } + runtime.KeepAlive(src) + return int(sp - uintptr(rt.IndexChar(src, 0))) +} + +func decodeNull(src string, pos int) (ret int) { + ret = pos + 4 + if ret > len(src) { + return -int(types.ERR_EOF) + } + if src[pos:ret] == bytesNull { + return ret + } else { + return -int(types.ERR_INVALID_CHAR) + } +} + +func decodeTrue(src string, pos int) (ret int) { + ret = pos + 4 + if ret > len(src) { + return -int(types.ERR_EOF) + } + if src[pos:ret] == bytesTrue { + return ret + } else { + return -int(types.ERR_INVALID_CHAR) + } + +} + +func decodeFalse(src string, pos int) (ret int) { + ret = pos + 5 + if ret > len(src) { + return -int(types.ERR_EOF) + } + if src[pos:ret] == bytesFalse { + return ret + } + return -int(types.ERR_INVALID_CHAR) +} + +func decodeString(src string, pos int) (ret int, v string) { + ret, ep := skipString(src, pos) + if ep == -1 { + (*rt.GoString)(unsafe.Pointer(&v)).Ptr = rt.IndexChar(src, pos+1) + (*rt.GoString)(unsafe.Pointer(&v)).Len = ret - pos - 2 + return ret, v + } + + vv, ok := unquoteBytes(rt.Str2Mem(src[pos:ret])) + if !ok { + return -int(types.ERR_INVALID_CHAR), "" + } + + runtime.KeepAlive(src) + return ret, rt.Mem2Str(vv) +} + +func decodeBinary(src string, pos int) (ret int, v []byte) { + var vv string + ret, vv = decodeString(src, pos) + if ret < 0 { + return ret, nil + } + var err error + v, err = base64.StdEncoding.DecodeString(vv) + if err != nil { + return -int(types.ERR_INVALID_CHAR), nil + } + return ret, v +} + +func isDigit(c byte) bool { + return c >= '0' && c <= '9' +} + +func decodeInt64(src string, pos int) (ret int, v int64, err error) { + sp := uintptr(rt.IndexChar(src, pos)) + ss := uintptr(sp) + se := uintptr(rt.IndexChar(src, len(src))) + if uintptr(sp) >= se { + return -int(types.ERR_EOF), 0, nil + } + + if c := *(*byte)(unsafe.Pointer(sp)); c == '-' { + sp += 1 + } + if sp == se { + return -int(types.ERR_EOF), 0, nil + } + + for ; sp < se; sp += uintptr(1) { + if !isDigit(*(*byte)(unsafe.Pointer(sp))) { + break + } + } + + if sp < se { + if c := *(*byte)(unsafe.Pointer(sp)); c == '.' || c == 'e' || c == 'E' { + return -int(types.ERR_INVALID_NUMBER_FMT), 0, nil + } + } + + var vv string + ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)) + (*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss) + (*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos + + v, err = strconv.ParseInt(vv, 10, 64) + if err != nil { + //NOTICE: allow overflow here + if err.(*strconv.NumError).Err == strconv.ErrRange { + return ret, 0, err + } + return -int(types.ERR_INVALID_CHAR), 0, err + } + + runtime.KeepAlive(src) + return ret, v, nil +} + +func isNumberChars(c byte) bool { + return (c >= '0' && c <= '9') || c == '+' || c == '-' || c == 'e' || c == 'E' || c == '.' +} + +func decodeFloat64(src string, pos int) (ret int, v float64, err error) { + sp := uintptr(rt.IndexChar(src, pos)) + ss := uintptr(sp) + se := uintptr(rt.IndexChar(src, len(src))) + if uintptr(sp) >= se { + return -int(types.ERR_EOF), 0, nil + } + + if c := *(*byte)(unsafe.Pointer(sp)); c == '-' { + sp += 1 + } + if sp == se { + return -int(types.ERR_EOF), 0, nil + } + + for ; sp < se; sp += uintptr(1) { + if !isNumberChars(*(*byte)(unsafe.Pointer(sp))) { + break + } + } + + var vv string + ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)) + (*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss) + (*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos + + v, err = strconv.ParseFloat(vv, 64) + if err != nil { + //NOTICE: allow overflow here + if err.(*strconv.NumError).Err == strconv.ErrRange { + return ret, 0, err + } + return -int(types.ERR_INVALID_CHAR), 0, err + } + + runtime.KeepAlive(src) + return ret, v, nil +} + +func decodeValue(src string, pos int) (ret int, v types.JsonState) { + pos = skipBlank(src, pos) + if pos < 0 { + return pos, types.JsonState{Vt: types.ValueType(pos)} + } + switch c := src[pos]; c { + case 'n': + ret = decodeNull(src, pos) + if ret < 0 { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + return ret, types.JsonState{Vt: types.V_NULL} + case '"': + var ep int + ret, ep = skipString(src, pos) + if ret < 0 { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + return ret, types.JsonState{Vt: types.V_STRING, Iv: int64(pos + 1), Ep: ep} + case '{': + return pos + 1, types.JsonState{Vt: types.V_OBJECT} + case '[': + return pos + 1, types.JsonState{Vt: types.V_ARRAY} + case 't': + ret = decodeTrue(src, pos) + if ret < 0 { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + return ret, types.JsonState{Vt: types.V_TRUE} + case 'f': + ret = decodeFalse(src, pos) + if ret < 0 { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + return ret, types.JsonState{Vt: types.V_FALSE} + case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + var iv int64 + ret, iv, _ = decodeInt64(src, pos) + if ret >= 0 { + return ret, types.JsonState{Vt: types.V_INTEGER, Iv: iv, Ep: pos} + } else if ret != -int(types.ERR_INVALID_NUMBER_FMT) { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + var fv float64 + ret, fv, _ = decodeFloat64(src, pos) + if ret >= 0 { + return ret, types.JsonState{Vt: types.V_DOUBLE, Dv: fv, Ep: pos} + } else { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + default: + return -int(types.ERR_INVALID_CHAR), types.JsonState{Vt:-types.ValueType(types.ERR_INVALID_CHAR)} + } +} + +func skipNumber(src string, pos int) (ret int) { + sp := uintptr(rt.IndexChar(src, pos)) + se := uintptr(rt.IndexChar(src, len(src))) + if uintptr(sp) >= se { + return -int(types.ERR_EOF) + } + + if c := *(*byte)(unsafe.Pointer(sp)); c == '-' { + sp += 1 + } + ss := sp + + var pointer bool + var exponent bool + var lastIsDigit bool + var nextNeedDigit = true + + for ; sp < se; sp += uintptr(1) { + c := *(*byte)(unsafe.Pointer(sp)) + if isDigit(c) { + lastIsDigit = true + nextNeedDigit = false + continue + } else if nextNeedDigit { + return -int(types.ERR_INVALID_CHAR) + } else if c == '.' { + if !lastIsDigit || pointer || sp == ss { + return -int(types.ERR_INVALID_CHAR) + } + pointer = true + lastIsDigit = false + nextNeedDigit = true + continue + } else if c == 'e' || c == 'E' { + if !lastIsDigit || exponent { + return -int(types.ERR_INVALID_CHAR) + } + if sp == se-1 { + return -int(types.ERR_EOF) + } + exponent = true + lastIsDigit = false + nextNeedDigit = false + continue + } else if c == '-' || c == '+' { + if prev := *(*byte)(unsafe.Pointer(sp - 1)); prev != 'e' && prev != 'E' { + return -int(types.ERR_INVALID_CHAR) + } + lastIsDigit = false + nextNeedDigit = true + continue + } else { + break + } + } + + if nextNeedDigit { + return -int(types.ERR_EOF) + } + + runtime.KeepAlive(src) + return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)) +} + +func skipString(src string, pos int) (ret int, ep int) { + if pos+1 >= len(src) { + return -int(types.ERR_EOF), -1 + } + + sp := uintptr(rt.IndexChar(src, pos)) + se := uintptr(rt.IndexChar(src, len(src))) + + if *(*byte)(unsafe.Pointer(sp)) != '"' { + return -int(types.ERR_INVALID_CHAR), -1 + } + sp += 1 + + ep = -1 + for sp < se { + c := *(*byte)(unsafe.Pointer(sp)) + if c == '\\' { + if ep == -1 { + ep = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)) + } + sp += 2 + continue + } + sp += 1 + if c == '"' { + break + } + } + + if sp > se { + return -int(types.ERR_EOF), -1 + } + + runtime.KeepAlive(src) + return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)), ep +} + +func skipPair(src string, pos int, lchar byte, rchar byte) (ret int) { + if pos+1 >= len(src) { + return -int(types.ERR_EOF) + } + + sp := uintptr(rt.IndexChar(src, pos)) + se := uintptr(rt.IndexChar(src, len(src))) + + if *(*byte)(unsafe.Pointer(sp)) != lchar { + return -int(types.ERR_INVALID_CHAR) + } + + sp += 1 + nbrace := 1 + inquote := false + + for sp < se { + c := *(*byte)(unsafe.Pointer(sp)) + if c == '\\' { + sp += 2 + continue + } else if c == '"' { + inquote = !inquote + } else if c == lchar { + if !inquote { + nbrace += 1 + } + } else if c == rchar { + if !inquote { + nbrace -= 1 + if nbrace == 0 { + sp += 1 + break + } + } + } + sp += 1 + } + + if nbrace != 0 { + return -int(types.ERR_INVALID_CHAR) + } + + runtime.KeepAlive(src) + return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)) +} + +func skipValue(src string, pos int) (ret int, start int) { + pos = skipBlank(src, pos) + if pos < 0 { + return pos, -1 + } + switch c := src[pos]; c { + case 'n': + ret = decodeNull(src, pos) + case '"': + ret, _ = skipString(src, pos) + case '{': + ret = skipPair(src, pos, '{', '}') + case '[': + ret = skipPair(src, pos, '[', ']') + case 't': + ret = decodeTrue(src, pos) + case 'f': + ret = decodeFalse(src, pos) + case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + ret = skipNumber(src, pos) + default: + ret = -int(types.ERR_INVALID_CHAR) + } + return ret, pos +} diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/encode.go b/ihub/vendor/github.com/bytedance/sonic/ast/encode.go new file mode 100644 index 0000000..1187e30 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/encode.go @@ -0,0 +1,259 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + `sync` + `unicode/utf8` + + `github.com/bytedance/sonic/internal/rt` +) + +const ( + _MaxBuffer = 1024 // 1KB buffer size +) + +func quoteString(e *[]byte, s string) { + *e = append(*e, '"') + start := 0 + for i := 0; i < len(s); { + if b := s[i]; b < utf8.RuneSelf { + if safeSet[b] { + i++ + continue + } + if start < i { + *e = append(*e, s[start:i]...) + } + *e = append(*e, '\\') + switch b { + case '\\', '"': + *e = append(*e, b) + case '\n': + *e = append(*e, 'n') + case '\r': + *e = append(*e, 'r') + case '\t': + *e = append(*e, 't') + default: + // This encodes bytes < 0x20 except for \t, \n and \r. + // If escapeHTML is set, it also escapes <, >, and & + // because they can lead to security holes when + // user-controlled strings are rendered into JSON + // and served to some browsers. + *e = append(*e, `u00`...) + *e = append(*e, hex[b>>4]) + *e = append(*e, hex[b&0xF]) + } + i++ + start = i + continue + } + c, size := utf8.DecodeRuneInString(s[i:]) + // if c == utf8.RuneError && size == 1 { + // if start < i { + // e.Write(s[start:i]) + // } + // e.WriteString(`\ufffd`) + // i += size + // start = i + // continue + // } + if c == '\u2028' || c == '\u2029' { + if start < i { + *e = append(*e, s[start:i]...) + } + *e = append(*e, `\u202`...) + *e = append(*e, hex[c&0xF]) + i += size + start = i + continue + } + i += size + } + if start < len(s) { + *e = append(*e, s[start:]...) + } + *e = append(*e, '"') +} + +var bytesPool = sync.Pool{} + +func (self *Node) MarshalJSON() ([]byte, error) { + buf := newBuffer() + err := self.encode(buf) + if err != nil { + freeBuffer(buf) + return nil, err + } + + ret := make([]byte, len(*buf)) + copy(ret, *buf) + freeBuffer(buf) + return ret, err +} + +func newBuffer() *[]byte { + if ret := bytesPool.Get(); ret != nil { + return ret.(*[]byte) + } else { + buf := make([]byte, 0, _MaxBuffer) + return &buf + } +} + +func freeBuffer(buf *[]byte) { + *buf = (*buf)[:0] + bytesPool.Put(buf) +} + +func (self *Node) encode(buf *[]byte) error { + if self.IsRaw() { + return self.encodeRaw(buf) + } + switch self.Type() { + case V_NONE : return ErrNotExist + case V_ERROR : return self.Check() + case V_NULL : return self.encodeNull(buf) + case V_TRUE : return self.encodeTrue(buf) + case V_FALSE : return self.encodeFalse(buf) + case V_ARRAY : return self.encodeArray(buf) + case V_OBJECT: return self.encodeObject(buf) + case V_STRING: return self.encodeString(buf) + case V_NUMBER: return self.encodeNumber(buf) + case V_ANY : return self.encodeInterface(buf) + default : return ErrUnsupportType + } +} + +func (self *Node) encodeRaw(buf *[]byte) error { + raw, err := self.Raw() + if err != nil { + return err + } + *buf = append(*buf, raw...) + return nil +} + +func (self *Node) encodeNull(buf *[]byte) error { + *buf = append(*buf, bytesNull...) + return nil +} + +func (self *Node) encodeTrue(buf *[]byte) error { + *buf = append(*buf, bytesTrue...) + return nil +} + +func (self *Node) encodeFalse(buf *[]byte) error { + *buf = append(*buf, bytesFalse...) + return nil +} + +func (self *Node) encodeNumber(buf *[]byte) error { + str := rt.StrFrom(self.p, self.v) + *buf = append(*buf, str...) + return nil +} + +func (self *Node) encodeString(buf *[]byte) error { + if self.v == 0 { + *buf = append(*buf, '"', '"') + return nil + } + + quote(buf, rt.StrFrom(self.p, self.v)) + return nil +} + +func (self *Node) encodeArray(buf *[]byte) error { + if self.isLazy() { + if err := self.skipAllIndex(); err != nil { + return err + } + } + + nb := self.len() + if nb == 0 { + *buf = append(*buf, bytesArray...) + return nil + } + + *buf = append(*buf, '[') + + var p = (*Node)(self.p) + err := p.encode(buf) + if err != nil { + return err + } + for i := 1; i < nb; i++ { + *buf = append(*buf, ',') + p = p.unsafe_next() + err := p.encode(buf) + if err != nil { + return err + } + } + + *buf = append(*buf, ']') + return nil +} + +func (self *Pair) encode(buf *[]byte) error { + if len(*buf) == 0 { + *buf = append(*buf, '"', '"', ':') + return self.Value.encode(buf) + } + + quote(buf, self.Key) + *buf = append(*buf, ':') + + return self.Value.encode(buf) +} + +func (self *Node) encodeObject(buf *[]byte) error { + if self.isLazy() { + if err := self.skipAllKey(); err != nil { + return err + } + } + + nb := self.len() + if nb == 0 { + *buf = append(*buf, bytesObject...) + return nil + } + + *buf = append(*buf, '{') + + var p = (*Pair)(self.p) + err := p.encode(buf) + if err != nil { + return err + } + for i := 1; i < nb; i++ { + *buf = append(*buf, ',') + p = p.unsafe_next() + err := p.encode(buf) + if err != nil { + return err + } + } + + *buf = append(*buf, '}') + return nil +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/error.go b/ihub/vendor/github.com/bytedance/sonic/ast/error.go new file mode 100644 index 0000000..f4c441a --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/error.go @@ -0,0 +1,98 @@ +package ast + +import ( + `fmt` + `strings` + `unsafe` + + `github.com/bytedance/sonic/internal/native/types` +) + +func (self *Parser) syntaxError(err types.ParsingError) SyntaxError { + return SyntaxError{ + Pos : self.p, + Src : self.s, + Code: err, + } +} + +func newSyntaxError(err SyntaxError) *Node { + msg := err.Description() + return &Node{ + t: V_ERROR, + v: int64(err.Code), + p: unsafe.Pointer(&msg), + } +} + +type SyntaxError struct { + Pos int + Src string + Code types.ParsingError + Msg string +} + +func (self SyntaxError) Error() string { + return fmt.Sprintf("%q", self.Description()) +} + +func (self SyntaxError) Description() string { + return "Syntax error " + self.description() +} + +func (self SyntaxError) description() string { + i := 16 + p := self.Pos - i + q := self.Pos + i + + /* check for empty source */ + if self.Src == "" { + return fmt.Sprintf("no sources available: %#v", self) + } + + /* prevent slicing before the beginning */ + if p < 0 { + p, q, i = 0, q - p, i + p + } + + /* prevent slicing beyond the end */ + if n := len(self.Src); q > n { + n = q - n + q = len(self.Src) + + /* move the left bound if possible */ + if p > n { + i += n + p -= n + } + } + + /* left and right length */ + x := clamp_zero(i) + y := clamp_zero(q - p - i - 1) + + /* compose the error description */ + return fmt.Sprintf( + "at index %d: %s\n\n\t%s\n\t%s^%s\n", + self.Pos, + self.Message(), + self.Src[p:q], + strings.Repeat(".", x), + strings.Repeat(".", y), + ) +} + +func (self SyntaxError) Message() string { + if self.Msg == "" { + return self.Code.Message() + } + return self.Msg +} + +func clamp_zero(v int) int { + if v < 0 { + return 0 + } else { + return v + } +} diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/iterator.go b/ihub/vendor/github.com/bytedance/sonic/ast/iterator.go new file mode 100644 index 0000000..03a25b4 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/iterator.go @@ -0,0 +1,164 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + `fmt` + + `github.com/bytedance/sonic/internal/native/types` +) + +type Pair struct { + Key string + Value Node +} + +// Values returns iterator for array's children traversal +func (self *Node) Values() (ListIterator, error) { + if err := self.should(types.V_ARRAY, "an array"); err != nil { + return ListIterator{}, err + } + return ListIterator{Iterator{p: self}}, nil +} + +// Properties returns iterator for object's children traversal +func (self *Node) Properties() (ObjectIterator, error) { + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return ObjectIterator{}, err + } + return ObjectIterator{Iterator{p: self}}, nil +} + +type Iterator struct { + i int + p *Node +} + +func (self *Iterator) Pos() int { + return self.i +} + +func (self *Iterator) Len() int { + return self.p.len() +} + +// HasNext reports if it is the end of iteration or has error. +func (self *Iterator) HasNext() bool { + if !self.p.isLazy() { + return self.p.Valid() && self.i < self.p.len() + } else if self.p.t == _V_ARRAY_LAZY { + return self.p.skipNextNode().Valid() + } else if self.p.t == _V_OBJECT_LAZY { + pair := self.p.skipNextPair() + if pair == nil { + return false + } + return pair.Value.Valid() + } + return false +} + +// ListIterator is specialized iterator for V_ARRAY +type ListIterator struct { + Iterator +} + +// ObjectIterator is specialized iterator for V_ARRAY +type ObjectIterator struct { + Iterator +} + +// Next scans through children of underlying V_ARRAY, +// copies each child to v, and returns .HasNext(). +func (self *ListIterator) Next(v *Node) bool { + if !self.HasNext() { + return false + } else { + *v, self.i = *self.p.nodeAt(self.i), self.i + 1 + return true + } +} + +// Next scans through children of underlying V_OBJECT, +// copies each child to v, and returns .HasNext(). +func (self *ObjectIterator) Next(p *Pair) bool { + if !self.HasNext() { + return false + } else { + *p, self.i = *self.p.pairAt(self.i), self.i + 1 + return true + } +} + +// Sequence represents scanning path of single-layer nodes. +// Index indicates the value's order in both V_ARRAY and V_OBJECT json. +// Key is the value's key (for V_OBJECT json only, otherwise it will be nil). +type Sequence struct { + Index int + Key *string + // Level int +} + +// String is string representation of one Sequence +func (s Sequence) String() string { + k := "" + if s.Key != nil { + k = *s.Key + } + return fmt.Sprintf("Sequence(%d, %q)", s.Index, k) +} + +type Scanner func(path Sequence, node *Node) bool + +// 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, +// the node itself will be returned and Sequence.Index == -1. +func (self *Node) ForEach(sc Scanner) error { + switch self.itype() { + case types.V_ARRAY: + ns, err := self.UnsafeArray() + if err != nil { + return err + } + for i := range ns { + if !sc(Sequence{i, nil}, &ns[i]) { + return err + } + } + case types.V_OBJECT: + ns, err := self.UnsafeMap() + if err != nil { + return err + } + for i := range ns { + if !sc(Sequence{i, &ns[i].Key}, &ns[i].Value) { + return err + } + } + default: + sc(Sequence{-1, nil}, self) + } + return self.Check() +} + +type PairSlice []Pair + +func (self PairSlice) Sort() { + radixQsort(self, 0, maxDepth(len(self))) +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/node.go b/ihub/vendor/github.com/bytedance/sonic/ast/node.go new file mode 100644 index 0000000..0d37baf --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/node.go @@ -0,0 +1,1802 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + `encoding/json` + `fmt` + `strconv` + `unsafe` + `reflect` + + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` +) + +const ( + _CAP_BITS = 32 + _LEN_MASK = 1 << _CAP_BITS - 1 + + _NODE_SIZE = unsafe.Sizeof(Node{}) + _PAIR_SIZE = unsafe.Sizeof(Pair{}) +) + +const ( + _V_NONE types.ValueType = 0 + _V_NODE_BASE types.ValueType = 1 << 5 + _V_LAZY types.ValueType = 1 << 7 + _V_RAW types.ValueType = 1 << 8 + _V_NUMBER = _V_NODE_BASE + 1 + _V_ANY = _V_NODE_BASE + 2 + _V_ARRAY_LAZY = _V_LAZY | types.V_ARRAY + _V_OBJECT_LAZY = _V_LAZY | types.V_OBJECT + _MASK_LAZY = _V_LAZY - 1 + _MASK_RAW = _V_RAW - 1 +) + +const ( + V_NONE = 0 + V_ERROR = 1 + V_NULL = 2 + V_TRUE = 3 + V_FALSE = 4 + V_ARRAY = 5 + V_OBJECT = 6 + V_STRING = 7 + V_NUMBER = int(_V_NUMBER) + V_ANY = int(_V_ANY) +) + +var ( + byteType = rt.UnpackType(reflect.TypeOf(byte(0))) +) + +type Node struct { + v int64 + t types.ValueType + p unsafe.Pointer +} + +// UnmarshalJSON is just an adapter to json.Unmarshaler. +// If you want better performance, use Searcher.GetByPath() directly +func (self *Node) UnmarshalJSON(data []byte) (err error) { + *self, err = NewSearcher(string(data)).GetByPath() + return +} + +/** Node Type Accessor **/ + +// Type returns json type represented by the node +// It will be one of belows: +// V_NONE = 0 (empty node) +// V_ERROR = 1 (error node) +// V_NULL = 2 (json value `null`) +// V_TRUE = 3 (json value `true`) +// V_FALSE = 4 (json value `false`) +// V_ARRAY = 5 (json value array) +// V_OBJECT = 6 (json value object) +// V_STRING = 7 (json value string) +// V_NUMBER = 33 (json value number ) +// V_ANY = 34 (golang interface{}) +func (self Node) Type() int { + return int(self.t & _MASK_LAZY & _MASK_RAW) +} + +func (self Node) itype() types.ValueType { + return self.t & _MASK_LAZY & _MASK_RAW +} + +// Exists returns false only if the self is nil or empty node V_NONE +func (self *Node) Exists() bool { + return self != nil && self.t != _V_NONE +} + +// Valid reports if self is NOT V_ERROR or nil +func (self *Node) Valid() bool { + if self == nil { + return false + } + return self.t != V_ERROR +} + +// Check checks if the node itself is valid, and return: +// - ErrNotFound If the node is nil +// - Its underlying error If the node is V_ERROR +func (self *Node) Check() error { + if self == nil { + return ErrNotExist + } else if self.t != V_ERROR { + return nil + } else { + return self + } +} + +// Error returns error message if the node is invalid +func (self Node) Error() string { + if self.t != V_ERROR { + return "" + } else { + return *(*string)(self.p) + } +} + +// IsRaw returns true if node's underlying value is raw json +func (self Node) IsRaw() bool { + return self.t&_V_RAW != 0 +} + +func (self *Node) isLazy() bool { + return self != nil && self.t&_V_LAZY != 0 +} + +func (self *Node) isAny() bool { + return self != nil && self.t == _V_ANY +} + +/** Simple Value Methods **/ + +// Raw returns json representation of the node, +func (self *Node) Raw() (string, error) { + if !self.IsRaw() { + buf, err := self.MarshalJSON() + return rt.Mem2Str(buf), err + } + return rt.StrFrom(self.p, self.v), nil +} + +func (self *Node) checkRaw() error { + if err := self.Check(); err != nil { + return err + } + if self.IsRaw() { + self.parseRaw(false) + } + return nil +} + +// Bool returns bool value represented by this node, +// including types.V_TRUE|V_FALSE|V_NUMBER|V_STRING|V_ANY|V_NULL, +// V_NONE will return error +func (self *Node) Bool() (bool, error) { + if err := self.checkRaw(); err != nil { + return false, err + } + switch self.t { + case types.V_TRUE : return true , nil + case types.V_FALSE : return false, nil + case types.V_NULL : return false, nil + case _V_NUMBER : + if i, err := numberToInt64(self); err == nil { + return i != 0, nil + } else if f, err := numberToFloat64(self); err == nil { + return f != 0, nil + } else { + return false, err + } + case types.V_STRING: return strconv.ParseBool(rt.StrFrom(self.p, self.v)) + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : return v, nil + case int : return v != 0, nil + case int8 : return v != 0, nil + case int16 : return v != 0, nil + case int32 : return v != 0, nil + case int64 : return v != 0, nil + case uint : return v != 0, nil + case uint8 : return v != 0, nil + case uint16 : return v != 0, nil + case uint32 : return v != 0, nil + case uint64 : return v != 0, nil + case float32: return v != 0, nil + case float64: return v != 0, nil + case string : return strconv.ParseBool(v) + case json.Number: + if i, err := v.Int64(); err == nil { + return i != 0, nil + } else if f, err := v.Float64(); err == nil { + return f != 0, nil + } else { + return false, err + } + default: return false, ErrUnsupportType + } + default : return false, ErrUnsupportType + } +} + +// Int64 casts the node to int64 value, +// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING +// V_NONE it will return error +func (self *Node) Int64() (int64, error) { + if err := self.checkRaw(); err != nil { + return 0, err + } + switch self.t { + case _V_NUMBER, types.V_STRING : + if i, err := numberToInt64(self); err == nil { + return i, nil + } else if f, err := numberToFloat64(self); err == nil { + return int64(f), nil + } else { + return 0, err + } + case types.V_TRUE : return 1, nil + case types.V_FALSE : return 0, nil + case types.V_NULL : return 0, nil + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : if v { return 1, nil } else { return 0, nil } + case int : return int64(v), nil + case int8 : return int64(v), nil + case int16 : return int64(v), nil + case int32 : return int64(v), nil + case int64 : return int64(v), nil + case uint : return int64(v), nil + case uint8 : return int64(v), nil + case uint16 : return int64(v), nil + case uint32 : return int64(v), nil + case uint64 : return int64(v), nil + case float32: return int64(v), nil + case float64: return int64(v), nil + case string : + if i, err := strconv.ParseInt(v, 10, 64); err == nil { + return i, nil + } else if f, err := strconv.ParseFloat(v, 64); err == nil { + return int64(f), nil + } else { + return 0, err + } + case json.Number: + if i, err := v.Int64(); err == nil { + return i, nil + } else if f, err := v.Float64(); err == nil { + return int64(f), nil + } else { + return 0, err + } + default: return 0, ErrUnsupportType + } + default : return 0, ErrUnsupportType + } +} + +// StrictInt64 exports underlying int64 value, including V_NUMBER, V_ANY +func (self *Node) StrictInt64() (int64, error) { + if err := self.checkRaw(); err != nil { + return 0, err + } + switch self.t { + case _V_NUMBER : return numberToInt64(self) + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case int : return int64(v), nil + case int8 : return int64(v), nil + case int16 : return int64(v), nil + case int32 : return int64(v), nil + case int64 : return int64(v), nil + case uint : return int64(v), nil + case uint8 : return int64(v), nil + case uint16: return int64(v), nil + case uint32: return int64(v), nil + case uint64: return int64(v), nil + case json.Number: + if i, err := v.Int64(); err == nil { + return i, nil + } else { + return 0, err + } + default: return 0, ErrUnsupportType + } + default : return 0, ErrUnsupportType + } +} + +func castNumber(v bool) json.Number { + if v { + return json.Number("1") + } else { + return json.Number("0") + } +} + +// Number casts node to float64, +// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL, +// V_NONE it will return error +func (self *Node) Number() (json.Number, error) { + if err := self.checkRaw(); err != nil { + return json.Number(""), err + } + switch self.t { + case _V_NUMBER : return toNumber(self) , nil + case types.V_STRING : + if _, err := numberToInt64(self); err == nil { + return toNumber(self), nil + } else if _, err := numberToFloat64(self); err == nil { + return toNumber(self), nil + } else { + return json.Number(""), err + } + case types.V_TRUE : return json.Number("1"), nil + case types.V_FALSE : return json.Number("0"), nil + case types.V_NULL : return json.Number("0"), nil + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : return castNumber(v), nil + case int : return castNumber(v != 0), nil + case int8 : return castNumber(v != 0), nil + case int16 : return castNumber(v != 0), nil + case int32 : return castNumber(v != 0), nil + case int64 : return castNumber(v != 0), nil + case uint : return castNumber(v != 0), nil + case uint8 : return castNumber(v != 0), nil + case uint16 : return castNumber(v != 0), nil + case uint32 : return castNumber(v != 0), nil + case uint64 : return castNumber(v != 0), nil + case float32: return castNumber(v != 0), nil + case float64: return castNumber(v != 0), nil + case string : + if _, err := strconv.ParseFloat(v, 64); err == nil { + return json.Number(v), nil + } else { + return json.Number(""), err + } + case json.Number: return v, nil + default: return json.Number(""), ErrUnsupportType + } + default : return json.Number(""), ErrUnsupportType + } +} + +// Number exports underlying float64 value, including V_NUMBER, V_ANY of json.Number +func (self *Node) StrictNumber() (json.Number, error) { + if err := self.checkRaw(); err != nil { + return json.Number(""), err + } + switch self.t { + case _V_NUMBER : return toNumber(self) , nil + case _V_ANY : + if v, ok := self.packAny().(json.Number); ok { + return v, nil + } else { + return json.Number(""), ErrUnsupportType + } + default : return json.Number(""), ErrUnsupportType + } +} + +// String cast node to string, +// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL, +// V_NONE it will return error +func (self *Node) String() (string, error) { + if err := self.checkRaw(); err != nil { + return "", err + } + switch self.t { + case types.V_NULL : return "" , nil + case types.V_TRUE : return "true" , nil + case types.V_FALSE : return "false", nil + case types.V_STRING, _V_NUMBER : return rt.StrFrom(self.p, self.v), nil + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : return strconv.FormatBool(v), nil + case int : return strconv.Itoa(v), nil + case int8 : return strconv.Itoa(int(v)), nil + case int16 : return strconv.Itoa(int(v)), nil + case int32 : return strconv.Itoa(int(v)), nil + case int64 : return strconv.Itoa(int(v)), nil + case uint : return strconv.Itoa(int(v)), nil + case uint8 : return strconv.Itoa(int(v)), nil + case uint16 : return strconv.Itoa(int(v)), nil + case uint32 : return strconv.Itoa(int(v)), nil + case uint64 : return strconv.Itoa(int(v)), nil + case float32: return strconv.FormatFloat(float64(v), 'g', -1, 64), nil + case float64: return strconv.FormatFloat(float64(v), 'g', -1, 64), nil + case string : return v, nil + case json.Number: return v.String(), nil + default: return "", ErrUnsupportType + } + default : return "" , ErrUnsupportType + } +} + +// StrictString returns string value (unescaped), includeing 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 { + return "", err + } + switch self.t { + case types.V_STRING : return rt.StrFrom(self.p, self.v), nil + case _V_ANY : + if v, ok := self.packAny().(string); ok { + return v, nil + } else { + return "", ErrUnsupportType + } + default : return "", ErrUnsupportType + } +} + +// Float64 cast node to float64, +// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL, +// V_NONE it will return error +func (self *Node) Float64() (float64, error) { + if err := self.checkRaw(); err != nil { + return 0.0, err + } + switch self.t { + case _V_NUMBER, types.V_STRING : return numberToFloat64(self) + case types.V_TRUE : return 1.0, nil + case types.V_FALSE : return 0.0, nil + case types.V_NULL : return 0.0, nil + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : + if v { + return 1.0, nil + } else { + return 0.0, nil + } + case int : return float64(v), nil + case int8 : return float64(v), nil + case int16 : return float64(v), nil + case int32 : return float64(v), nil + case int64 : return float64(v), nil + case uint : return float64(v), nil + case uint8 : return float64(v), nil + case uint16 : return float64(v), nil + case uint32 : return float64(v), nil + case uint64 : return float64(v), nil + case float32: return float64(v), nil + case float64: return float64(v), nil + case string : + if f, err := strconv.ParseFloat(v, 64); err == nil { + return float64(f), nil + } else { + return 0, err + } + case json.Number: + if f, err := v.Float64(); err == nil { + return float64(f), nil + } else { + return 0, err + } + default : return 0, ErrUnsupportType + } + default : return 0.0, ErrUnsupportType + } +} + +// Float64 exports underlying float64 value, includeing V_NUMBER, V_ANY +func (self *Node) StrictFloat64() (float64, error) { + if err := self.checkRaw(); err != nil { + return 0.0, err + } + switch self.t { + case _V_NUMBER : return numberToFloat64(self) + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case float32 : return float64(v), nil + case float64 : return float64(v), nil + default : return 0, ErrUnsupportType + } + default : return 0.0, ErrUnsupportType + } +} + +/** Sequencial Value Methods **/ + +// Len returns children count of a array|object|string node +// For partially loaded node, it also works but only counts the parsed children +func (self *Node) Len() (int, error) { + if err := self.checkRaw(); err != nil { + return 0, err + } + if self.t == types.V_ARRAY || self.t == types.V_OBJECT || self.t == _V_ARRAY_LAZY || self.t == _V_OBJECT_LAZY { + return int(self.v & _LEN_MASK), nil + } else if self.t == types.V_STRING { + return int(self.v), nil + } else if self.t == _V_NONE || self.t == types.V_NULL { + return 0, nil + } else { + return 0, ErrUnsupportType + } +} + +func (self Node) len() int { + return int(self.v & _LEN_MASK) +} + +// Cap returns malloc capacity of a array|object node for children +func (self *Node) Cap() (int, error) { + if err := self.checkRaw(); err != nil { + return 0, err + } + if self.t == types.V_ARRAY || self.t == types.V_OBJECT || self.t == _V_ARRAY_LAZY || self.t == _V_OBJECT_LAZY { + return int(self.v >> _CAP_BITS), nil + } else if self.t == _V_NONE || self.t == types.V_NULL { + return 0, nil + } else { + return 0, ErrUnsupportType + } +} + +func (self Node) cap() int { + return int(self.v >> _CAP_BITS) +} + +// Set sets the node of given key under self, and reports if the key has existed. +// +// If self is V_NONE or V_NULL, it becomes V_OBJECT and sets the node at the key. +func (self *Node) Set(key string, node Node) (bool, error) { + if self != nil && (self.t == _V_NONE || self.t == types.V_NULL) { + *self = NewObject([]Pair{{key, node}}) + return false, nil + } + + if err := node.Check(); err != nil { + return false, err + } + + p := self.Get(key) + if !p.Exists() { + l := self.len() + c := self.cap() + if l == c { + // TODO: maybe change append size in future + c += _DEFAULT_NODE_CAP + mem := unsafe_NewArray(_PAIR_TYPE, c) + memmove(mem, self.p, _PAIR_SIZE * uintptr(l)) + self.p = mem + } + v := self.pairAt(l) + v.Key = key + v.Value = node + self.setCapAndLen(c, l+1) + return false, nil + + } else if err := p.Check(); err != nil { + return false, err + } + + *p = node + return true, nil +} + +// SetAny wraps val with V_ANY node, and Set() the node. +func (self *Node) SetAny(key string, val interface{}) (bool, error) { + return self.Set(key, NewAny(val)) +} + +// Unset remove the node of given key under object parent, and reports if the key has existed. +func (self *Node) Unset(key string) (bool, error) { + self.must(types.V_OBJECT, "an object") + p, i := self.skipKey(key) + if !p.Exists() { + return false, nil + } else if err := p.Check(); err != nil { + return false, err + } + + self.removePair(i) + return true, nil +} + +// SetByIndex sets the node of given index, and reports if the key has existed. +// +// The index must be within self's children. +func (self *Node) SetByIndex(index int, node Node) (bool, error) { + if err := node.Check(); err != nil { + return false, err + } + + p := self.Index(index) + if !p.Exists() { + return false, ErrNotExist + } else if err := p.Check(); err != nil { + return false, err + } + + *p = node + return true, nil +} + +// SetAny wraps val with V_ANY node, and SetByIndex() the node. +func (self *Node) SetAnyByIndex(index int, val interface{}) (bool, error) { + return self.SetByIndex(index, NewAny(val)) +} + +// UnsetByIndex remove the node of given index +func (self *Node) UnsetByIndex(index int) (bool, error) { + var p *Node + it := self.itype() + if it == types.V_ARRAY { + p = self.Index(index) + }else if it == types.V_OBJECT { + pr := self.skipIndexPair(index) + if pr == nil { + return false, ErrNotExist + } + p = &pr.Value + } else { + return false, ErrUnsupportType + } + + if !p.Exists() { + return false, ErrNotExist + } + + if it == types.V_ARRAY { + self.removeNode(index) + }else if it == types.V_OBJECT { + self.removePair(index) + } + return true, nil +} + +// Add appends the given node under self. +// +// If self is V_NONE or V_NULL, it becomes V_ARRAY and sets the node at index 0. +func (self *Node) Add(node Node) error { + if self != nil && (self.t == _V_NONE || self.t == types.V_NULL) { + *self = NewArray([]Node{node}) + return nil + } + + if err := self.should(types.V_ARRAY, "an array"); err != nil { + return err + } + if err := self.skipAllIndex(); err != nil { + return err + } + + var p rt.GoSlice + p.Cap = self.cap() + p.Len = self.len() + p.Ptr = self.p + + s := *(*[]Node)(unsafe.Pointer(&p)) + s = append(s, node) + + self.p = unsafe.Pointer(&s[0]) + self.setCapAndLen(cap(s), len(s)) + return nil +} + +// SetAny wraps val with V_ANY node, and Add() the node. +func (self *Node) AddAny(val interface{}) error { + return self.Add(NewAny(val)) +} + +// GetByPath load given path on demands, +// which only ensure nodes before this path got parsed. +// +// Note, the api expects the json is well-formed at least, +// otherwise it may return unexpected result. +func (self *Node) GetByPath(path ...interface{}) *Node { + if !self.Valid() { + return self + } + var s = self + for _, p := range path { + switch p := p.(type) { + case int: + s = s.Index(p) + if !s.Valid() { + return s + } + case string: + s = s.Get(p) + if !s.Valid() { + return s + } + default: + panic("path must be either int or string") + } + } + return s +} + +// Get loads given key of an object node on demands +func (self *Node) Get(key string) *Node { + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return unwrapError(err) + } + n, _ := self.skipKey(key) + return n +} + +// Index indexies node at given idx, +// node type CAN be either V_OBJECT or V_ARRAY +func (self *Node) Index(idx int) *Node { + if err := self.checkRaw(); err != nil { + return unwrapError(err) + } + + it := self.itype() + if it == types.V_ARRAY { + return self.skipIndex(idx) + + }else if it == types.V_OBJECT { + pr := self.skipIndexPair(idx) + if pr == nil { + return newError(_ERR_NOT_FOUND, "value not exists") + } + return &pr.Value + + } else { + return newError(_ERR_UNSUPPORT_TYPE, fmt.Sprintf("unsupported type: %v", self.itype())) + } +} + +// IndexPair indexies pair at given idx, +// node type MUST be either V_OBJECT +func (self *Node) IndexPair(idx int) *Pair { + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return nil + } + return self.skipIndexPair(idx) +} + +// IndexOrGet firstly use idx to index a value and check if its key matches +// If not, then use the key to search value +func (self *Node) IndexOrGet(idx int, key string) *Node { + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return unwrapError(err) + } + + pr := self.skipIndexPair(idx) + if pr != nil && pr.Key == key { + return &pr.Value + } + n, _ := self.skipKey(key) + return n +} + +/** Generic Value Converters **/ + +// Map loads all keys of an object node +func (self *Node) Map() (map[string]interface{}, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.(map[string]interface{}); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return nil, err + } + if err := self.loadAllKey(); err != nil { + return nil, err + } + return self.toGenericObject() +} + +// MapUseNumber loads all keys of an object node, with numeric nodes casted to json.Number +func (self *Node) MapUseNumber() (map[string]interface{}, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.(map[string]interface{}); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return nil, err + } + if err := self.loadAllKey(); err != nil { + return nil, err + } + return self.toGenericObjectUseNumber() +} + +// MapUseNode scans both parsed and non-parsed chidren nodes, +// and map them by their keys +func (self *Node) MapUseNode() (map[string]Node, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.(map[string]Node); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return nil, err + } + if err := self.skipAllKey(); err != nil { + return nil, err + } + return self.toGenericObjectUseNode() +} + +// MapUnsafe exports the underlying pointer to its children map +// WARN: don't use it unless you know what you are doing +func (self *Node) UnsafeMap() ([]Pair, error) { + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return nil, err + } + if err := self.skipAllKey(); err != nil { + return nil, err + } + s := rt.Ptr2SlicePtr(self.p, int(self.len()), self.cap()) + return *(*[]Pair)(s), nil +} + +// SortKeys sorts children of a V_OBJECT node in ascending key-order. +// If recurse is true, it recursively sorts children's children as long as a V_OBJECT node is found. +func (self *Node) SortKeys(recurse bool) (err error) { + ps, err := self.UnsafeMap() + if err != nil { + return err + } + PairSlice(ps).Sort() + if recurse { + var sc Scanner + sc = func(path Sequence, node *Node) bool { + if node.itype() == types.V_OBJECT { + if err := node.SortKeys(recurse); err != nil { + return false + } + } + if node.itype() == types.V_ARRAY { + if err := node.ForEach(sc); err != nil { + return false + } + } + return true + } + self.ForEach(sc) + } + return nil +} + +// Array loads all indexes of an array node +func (self *Node) Array() ([]interface{}, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.([]interface{}); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_ARRAY, "an array"); err != nil { + return nil, err + } + if err := self.loadAllIndex(); err != nil { + return nil, err + } + return self.toGenericArray() +} + +// ArrayUseNumber loads all indexes of an array node, with numeric nodes casted to json.Number +func (self *Node) ArrayUseNumber() ([]interface{}, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.([]interface{}); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_ARRAY, "an array"); err != nil { + return nil, err + } + if err := self.loadAllIndex(); err != nil { + return nil, err + } + return self.toGenericArrayUseNumber() +} + +// ArrayUseNode copys both parsed and non-parsed chidren nodes, +// and indexes them by original order +func (self *Node) ArrayUseNode() ([]Node, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.([]Node); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_ARRAY, "an array"); err != nil { + return nil, err + } + if err := self.skipAllIndex(); err != nil { + return nil, err + } + return self.toGenericArrayUseNode() +} + +// ArrayUnsafe exports the underlying pointer to its children array +// WARN: don't use it unless you know what you are doing +func (self *Node) UnsafeArray() ([]Node, error) { + if err := self.should(types.V_ARRAY, "an array"); err != nil { + return nil, err + } + if err := self.skipAllIndex(); err != nil { + return nil, err + } + s := rt.Ptr2SlicePtr(self.p, self.len(), self.cap()) + return *(*[]Node)(s), nil +} + +// Interface loads all children under all pathes from this node, +// and converts itself as generic type. +// WARN: all numberic nodes are casted to float64 +func (self *Node) Interface() (interface{}, error) { + if err := self.checkRaw(); err != nil { + return nil, err + } + switch self.t { + case V_ERROR : return nil, self.Check() + case types.V_NULL : return nil, nil + case types.V_TRUE : return true, nil + case types.V_FALSE : return false, nil + case types.V_ARRAY : return self.toGenericArray() + case types.V_OBJECT : return self.toGenericObject() + case types.V_STRING : return rt.StrFrom(self.p, self.v), nil + case _V_NUMBER : + v, err := numberToFloat64(self) + if err != nil { + return nil, err + } + return v, nil + case _V_ARRAY_LAZY : + if err := self.loadAllIndex(); err != nil { + return nil, err + } + return self.toGenericArray() + case _V_OBJECT_LAZY : + if err := self.loadAllKey(); err != nil { + return nil, err + } + return self.toGenericObject() + case _V_ANY: + switch v := self.packAny().(type) { + case Node : return v.Interface() + case *Node: return v.Interface() + default : return v, nil + } + default : return nil, ErrUnsupportType + } +} + +func (self *Node) packAny() interface{} { + return *(*interface{})(self.p) +} + +// InterfaceUseNumber works same with Interface() +// except numberic nodes are casted to json.Number +func (self *Node) InterfaceUseNumber() (interface{}, error) { + if err := self.checkRaw(); err != nil { + return nil, err + } + switch self.t { + case V_ERROR : return nil, self.Check() + case types.V_NULL : return nil, nil + case types.V_TRUE : return true, nil + case types.V_FALSE : return false, nil + case types.V_ARRAY : return self.toGenericArrayUseNumber() + case types.V_OBJECT : return self.toGenericObjectUseNumber() + case types.V_STRING : return rt.StrFrom(self.p, self.v), nil + case _V_NUMBER : return toNumber(self), nil + case _V_ARRAY_LAZY : + if err := self.loadAllIndex(); err != nil { + return nil, err + } + return self.toGenericArrayUseNumber() + case _V_OBJECT_LAZY : + if err := self.loadAllKey(); err != nil { + return nil, err + } + return self.toGenericObjectUseNumber() + case _V_ANY : return self.packAny(), nil + default : return nil, ErrUnsupportType + } +} + +// InterfaceUseNode clone itself as a new node, +// or its children as map[string]Node (or []Node) +func (self *Node) InterfaceUseNode() (interface{}, error) { + if err := self.checkRaw(); err != nil { + return nil, err + } + switch self.t { + case types.V_ARRAY : return self.toGenericArrayUseNode() + case types.V_OBJECT : return self.toGenericObjectUseNode() + case _V_ARRAY_LAZY : + if err := self.skipAllIndex(); err != nil { + return nil, err + } + return self.toGenericArrayUseNode() + case _V_OBJECT_LAZY : + if err := self.skipAllKey(); err != nil { + return nil, err + } + return self.toGenericObjectUseNode() + default : return *self, self.Check() + } +} + +// LoadAll loads all the node's children and children's children as parsed. +// After calling it, the node can be safely used on concurrency +func (self *Node) LoadAll() error { + if self.IsRaw() { + self.parseRaw(true) + return self.Check() + } + + switch self.itype() { + case types.V_ARRAY: + e := self.len() + if err := self.loadAllIndex(); err != nil { + return err + } + for i := 0; i < e; i++ { + n := self.nodeAt(i) + if n.IsRaw() { + n.parseRaw(true) + } + if err := n.Check(); err != nil { + return err + } + } + return nil + case types.V_OBJECT: + e := self.len() + if err := self.loadAllKey(); err != nil { + return err + } + for i := 0; i < e; i++ { + n := self.pairAt(i) + if n.Value.IsRaw() { + n.Value.parseRaw(true) + } + if err := n.Value.Check(); err != nil { + return err + } + } + return nil + default: + return self.Check() + } +} + +// Load loads the node's children as parsed. +// After calling it, only the node itself can be used on concurrency (not include its children) +func (self *Node) Load() error { + if self.IsRaw() { + self.parseRaw(false) + return self.Load() + } + + switch self.t { + case _V_ARRAY_LAZY: + return self.skipAllIndex() + case _V_OBJECT_LAZY: + return self.skipAllKey() + default: + return self.Check() + } +} + +/**---------------------------------- Internal Helper Methods ----------------------------------**/ + +var ( + _NODE_TYPE = rt.UnpackEface(Node{}).Type + _PAIR_TYPE = rt.UnpackEface(Pair{}).Type +) + +func (self *Node) setCapAndLen(cap int, len int) { + if self.t == types.V_ARRAY || self.t == types.V_OBJECT || self.t == _V_ARRAY_LAZY || self.t == _V_OBJECT_LAZY { + self.v = int64(len&_LEN_MASK | cap<<_CAP_BITS) + } else { + panic("value does not have a length") + } +} + +func (self *Node) unsafe_next() *Node { + return (*Node)(unsafe.Pointer(uintptr(unsafe.Pointer(self)) + _NODE_SIZE)) +} + +func (self *Pair) unsafe_next() *Pair { + return (*Pair)(unsafe.Pointer(uintptr(unsafe.Pointer(self)) + _PAIR_SIZE)) +} + +func (self *Node) must(t types.ValueType, s string) { + if err := self.checkRaw(); err != nil { + panic(err) + } + if err := self.Check(); err != nil { + panic(err) + } + if self.itype() != t { + panic("value cannot be represented as " + s) + } +} + +func (self *Node) should(t types.ValueType, s string) error { + if err := self.checkRaw(); err != nil { + return err + } + if self.itype() != t { + return ErrUnsupportType + } + return nil +} + +func (self *Node) nodeAt(i int) *Node { + var p = self.p + if self.isLazy() { + _, stack := self.getParserAndArrayStack() + p = *(*unsafe.Pointer)(unsafe.Pointer(&stack.v)) + } + return (*Node)(unsafe.Pointer(uintptr(p) + uintptr(i)*_NODE_SIZE)) +} + +func (self *Node) pairAt(i int) *Pair { + var p = self.p + if self.isLazy() { + _, stack := self.getParserAndObjectStack() + p = *(*unsafe.Pointer)(unsafe.Pointer(&stack.v)) + } + return (*Pair)(unsafe.Pointer(uintptr(p) + uintptr(i)*_PAIR_SIZE)) +} + +func (self *Node) getParserAndArrayStack() (*Parser, *parseArrayStack) { + stack := (*parseArrayStack)(self.p) + ret := (*rt.GoSlice)(unsafe.Pointer(&stack.v)) + ret.Len = self.len() + ret.Cap = self.cap() + return &stack.parser, stack +} + +func (self *Node) getParserAndObjectStack() (*Parser, *parseObjectStack) { + stack := (*parseObjectStack)(self.p) + ret := (*rt.GoSlice)(unsafe.Pointer(&stack.v)) + ret.Len = self.len() + ret.Cap = self.cap() + return &stack.parser, stack +} + +func (self *Node) skipAllIndex() error { + if !self.isLazy() { + return nil + } + var err types.ParsingError + parser, stack := self.getParserAndArrayStack() + parser.skipValue = true + parser.noLazy = true + *self, err = parser.decodeArray(stack.v) + if err != 0 { + return parser.ExportError(err) + } + return nil +} + +func (self *Node) skipAllKey() error { + if !self.isLazy() { + return nil + } + var err types.ParsingError + parser, stack := self.getParserAndObjectStack() + parser.skipValue = true + parser.noLazy = true + *self, err = parser.decodeObject(stack.v) + if err != 0 { + return parser.ExportError(err) + } + return nil +} + +func (self *Node) skipKey(key string) (*Node, int) { + nb := self.len() + lazy := self.isLazy() + + if nb > 0 { + /* linear search */ + var p *Pair + if lazy { + s := (*parseObjectStack)(self.p) + p = &s.v[0] + } else { + p = (*Pair)(self.p) + } + + if p.Key == key { + return &p.Value, 0 + } + for i := 1; i < nb; i++ { + p = p.unsafe_next() + if p.Key == key { + return &p.Value, i + } + } + } + + /* not found */ + if !lazy { + return nil, -1 + } + + // lazy load + for last, i := self.skipNextPair(), nb; last != nil; last, i = self.skipNextPair(), i+1 { + if last.Value.Check() != nil { + return &last.Value, -1 + } + if last.Key == key { + return &last.Value, i + } + } + + return nil, -1 +} + +func (self *Node) skipIndex(index int) *Node { + nb := self.len() + if nb > index { + v := self.nodeAt(index) + return v + } + if !self.isLazy() { + return nil + } + + // lazy load + for last := self.skipNextNode(); last != nil; last = self.skipNextNode(){ + if last.Check() != nil { + return last + } + if self.len() > index { + return last + } + } + + return nil +} + +func (self *Node) skipIndexPair(index int) *Pair { + nb := self.len() + if nb > index { + return self.pairAt(index) + } + if !self.isLazy() { + return nil + } + + // lazy load + for last := self.skipNextPair(); last != nil; last = self.skipNextPair(){ + if last.Value.Check() != nil { + return last + } + if self.len() > index { + return last + } + } + + return nil +} + +func (self *Node) loadAllIndex() error { + if !self.isLazy() { + return nil + } + var err types.ParsingError + parser, stack := self.getParserAndArrayStack() + parser.noLazy = true + *self, err = parser.decodeArray(stack.v) + if err != 0 { + return parser.ExportError(err) + } + return nil +} + +func (self *Node) loadAllKey() error { + if !self.isLazy() { + return nil + } + var err types.ParsingError + parser, stack := self.getParserAndObjectStack() + parser.noLazy = true + *self, err = parser.decodeObject(stack.v) + if err != 0 { + return parser.ExportError(err) + } + return nil +} + +func (self *Node) removeNode(i int) { + nb := self.len() - 1 + node := self.nodeAt(i) + if i == nb { + self.setCapAndLen(self.cap(), nb) + *node = Node{} + return + } + + from := self.nodeAt(i + 1) + memmove(unsafe.Pointer(node), unsafe.Pointer(from), _NODE_SIZE * uintptr(nb - i)) + + last := self.nodeAt(nb) + *last = Node{} + + self.setCapAndLen(self.cap(), nb) +} + +func (self *Node) removePair(i int) { + nb := self.len() - 1 + node := self.pairAt(i) + if i == nb { + self.setCapAndLen(self.cap(), nb) + *node = Pair{} + return + } + + from := self.pairAt(i + 1) + memmove(unsafe.Pointer(node), unsafe.Pointer(from), _PAIR_SIZE * uintptr(nb - i)) + + last := self.pairAt(nb) + *last = Pair{} + + self.setCapAndLen(self.cap(), nb) +} + +func (self *Node) toGenericArray() ([]interface{}, error) { + nb := self.len() + ret := make([]interface{}, nb) + if nb == 0 { + return ret, nil + } + + /* convert each item */ + var p = (*Node)(self.p) + x, err := p.Interface() + if err != nil { + return nil, err + } + ret[0] = x + + for i := 1; i < nb; i++ { + p = p.unsafe_next() + x, err := p.Interface() + if err != nil { + return nil, err + } + ret[i] = x + } + + /* all done */ + return ret, nil +} + +func (self *Node) toGenericArrayUseNumber() ([]interface{}, error) { + nb := self.len() + ret := make([]interface{}, nb) + if nb == 0 { + return ret, nil + } + + /* convert each item */ + var p = (*Node)(self.p) + x, err := p.InterfaceUseNumber() + if err != nil { + return nil, err + } + ret[0] = x + + for i := 1; i < nb; i++ { + p = p.unsafe_next() + x, err := p.InterfaceUseNumber() + if err != nil { + return nil, err + } + ret[i] = x + } + + /* all done */ + return ret, nil +} + +func (self *Node) toGenericArrayUseNode() ([]Node, error) { + var nb = self.len() + var out = make([]Node, nb) + if nb == 0 { + return out, nil + } + + var p = (*Node)(self.p) + out[0] = *p + if err := p.Check(); err != nil { + return nil, err + } + + for i := 1; i < nb; i++ { + p = p.unsafe_next() + if err := p.Check(); err != nil { + return nil, err + } + out[i] = *p + } + + return out, nil +} + +func (self *Node) toGenericObject() (map[string]interface{}, error) { + nb := self.len() + ret := make(map[string]interface{}, nb) + if nb == 0 { + return ret, nil + } + + /* convert each item */ + var p = (*Pair)(self.p) + x, err := p.Value.Interface() + if err != nil { + return nil, err + } + ret[p.Key] = x + + for i := 1; i < nb; i++ { + p = p.unsafe_next() + x, err := p.Value.Interface() + if err != nil { + return nil, err + } + ret[p.Key] = x + } + + /* all done */ + return ret, nil +} + + +func (self *Node) toGenericObjectUseNumber() (map[string]interface{}, error) { + nb := self.len() + ret := make(map[string]interface{}, nb) + if nb == 0 { + return ret, nil + } + + /* convert each item */ + var p = (*Pair)(self.p) + x, err := p.Value.InterfaceUseNumber() + if err != nil { + return nil, err + } + ret[p.Key] = x + + for i := 1; i < nb; i++ { + p = p.unsafe_next() + x, err := p.Value.InterfaceUseNumber() + if err != nil { + return nil, err + } + ret[p.Key] = x + } + + /* all done */ + return ret, nil +} + +func (self *Node) toGenericObjectUseNode() (map[string]Node, error) { + var nb = self.len() + var out = make(map[string]Node, nb) + if nb == 0 { + return out, nil + } + + var p = (*Pair)(self.p) + out[p.Key] = p.Value + if err := p.Value.Check(); err != nil { + return nil, err + } + + for i := 1; i < nb; i++ { + p = p.unsafe_next() + if err := p.Value.Check(); err != nil { + return nil, err + } + out[p.Key] = p.Value + } + + /* all done */ + return out, nil +} + +/**------------------------------------ Factory Methods ------------------------------------**/ + +var ( + nullNode = Node{t: types.V_NULL} + trueNode = Node{t: types.V_TRUE} + falseNode = Node{t: types.V_FALSE} + + emptyArrayNode = Node{t: types.V_ARRAY} + emptyObjectNode = Node{t: types.V_OBJECT} +) + +// NewRaw creates a node of raw json, and decides its type by first char. +func NewRaw(json string) Node { + if json == "" { + panic("empty json string") + } + it := switchRawType(json[0]) + return newRawNode(json, it) +} + +// NewAny creates a node of type V_ANY if any's type isn't Node or *Node, +// which stores interface{} and can be only used for `.Interface()`\`.MarshalJSON()`. +func NewAny(any interface{}) Node { + switch n := any.(type) { + case Node: + return n + case *Node: + return *n + default: + return Node{ + t: _V_ANY, + v: 0, + p: unsafe.Pointer(&any), + } + } +} + +// NewBytes encodes given src with Base64 (RFC 4648), and creates a node of type V_STRING. +func NewBytes(src []byte) Node { + if len(src) == 0 { + panic("empty src bytes") + } + out := encodeBase64(src) + return NewString(out) +} + +// NewNull creates a node of type V_NULL +func NewNull() Node { + return Node{ + v: 0, + p: nil, + t: types.V_NULL, + } +} + +// NewBool creates a node of type bool: +// If v is true, returns V_TRUE node +// If v is false, returns V_FALSE node +func NewBool(v bool) Node { + var t = types.V_FALSE + if v { + t = types.V_TRUE + } + return Node{ + v: 0, + p: nil, + t: t, + } +} + +// NewNumber creates a json.Number node +// v must be a decimal string complying with RFC8259 +func NewNumber(v string) Node { + return Node{ + v: int64(len(v) & _LEN_MASK), + p: rt.StrPtr(v), + t: _V_NUMBER, + } +} + +func toNumber(node *Node) json.Number { + return json.Number(rt.StrFrom(node.p, node.v)) +} + +func numberToFloat64(node *Node) (float64, error) { + ret,err := toNumber(node).Float64() + if err != nil { + return 0, err + } + return ret, nil +} + +func numberToInt64(node *Node) (int64, error) { + ret,err := toNumber(node).Int64() + if err != nil { + return 0, err + } + return ret, nil +} + +func newBytes(v []byte) Node { + return Node{ + t: types.V_STRING, + p: mem2ptr(v), + v: int64(len(v) & _LEN_MASK), + } +} + +// NewString creates a node of type V_STRING. +// v is considered to be a valid UTF-8 string, +// which means it won't be validated and unescaped. +// when the node is encoded to json, v will be escaped. +func NewString(v string) Node { + return Node{ + t: types.V_STRING, + p: rt.StrPtr(v), + v: int64(len(v) & _LEN_MASK), + } +} + +// NewArray creates a node of type V_ARRAY, +// using v as its underlying children +func NewArray(v []Node) Node { + return Node{ + t: types.V_ARRAY, + v: int64(len(v)&_LEN_MASK | cap(v)<<_CAP_BITS), + p: *(*unsafe.Pointer)(unsafe.Pointer(&v)), + } +} + +func (self *Node) setArray(v []Node) { + self.t = types.V_ARRAY + self.setCapAndLen(cap(v), len(v)) + self.p = *(*unsafe.Pointer)(unsafe.Pointer(&v)) +} + +// NewObject creates a node of type V_OBJECT, +// using v as its underlying children +func NewObject(v []Pair) Node { + return Node{ + t: types.V_OBJECT, + v: int64(len(v)&_LEN_MASK | cap(v)<<_CAP_BITS), + p: *(*unsafe.Pointer)(unsafe.Pointer(&v)), + } +} + +func (self *Node) setObject(v []Pair) { + self.t = types.V_OBJECT + self.setCapAndLen(cap(v), len(v)) + self.p = *(*unsafe.Pointer)(unsafe.Pointer(&v)) +} + +type parseObjectStack struct { + parser Parser + v []Pair +} + +type parseArrayStack struct { + parser Parser + v []Node +} + +func newLazyArray(p *Parser, v []Node) Node { + s := new(parseArrayStack) + s.parser = *p + s.v = v + return Node{ + t: _V_ARRAY_LAZY, + v: int64(len(v)&_LEN_MASK | cap(v)<<_CAP_BITS), + p: unsafe.Pointer(s), + } +} + +func (self *Node) setLazyArray(p *Parser, v []Node) { + s := new(parseArrayStack) + s.parser = *p + s.v = v + self.t = _V_ARRAY_LAZY + self.setCapAndLen(cap(v), len(v)) + self.p = (unsafe.Pointer)(s) +} + +func newLazyObject(p *Parser, v []Pair) Node { + s := new(parseObjectStack) + s.parser = *p + s.v = v + return Node{ + t: _V_OBJECT_LAZY, + v: int64(len(v)&_LEN_MASK | cap(v)<<_CAP_BITS), + p: unsafe.Pointer(s), + } +} + +func (self *Node) setLazyObject(p *Parser, v []Pair) { + s := new(parseObjectStack) + s.parser = *p + s.v = v + self.t = _V_OBJECT_LAZY + self.setCapAndLen(cap(v), len(v)) + self.p = (unsafe.Pointer)(s) +} + +func newRawNode(str string, typ types.ValueType) Node { + return Node{ + t: _V_RAW | typ, + p: rt.StrPtr(str), + v: int64(len(str) & _LEN_MASK), + } +} + +func (self *Node) parseRaw(full bool) { + raw := rt.StrFrom(self.p, self.v) + parser := NewParser(raw) + if full { + parser.noLazy = true + parser.skipValue = false + } + var e types.ParsingError + *self, e = parser.Parse() + if e != 0 { + *self = *newSyntaxError(parser.syntaxError(e)) + } +} + +func newError(err types.ParsingError, msg string) *Node { + return &Node{ + t: V_ERROR, + v: int64(err), + p: unsafe.Pointer(&msg), + } +} + +var typeJumpTable = [256]types.ValueType{ + '"' : types.V_STRING, + '-' : _V_NUMBER, + '0' : _V_NUMBER, + '1' : _V_NUMBER, + '2' : _V_NUMBER, + '3' : _V_NUMBER, + '4' : _V_NUMBER, + '5' : _V_NUMBER, + '6' : _V_NUMBER, + '7' : _V_NUMBER, + '8' : _V_NUMBER, + '9' : _V_NUMBER, + '[' : types.V_ARRAY, + 'f' : types.V_FALSE, + 'n' : types.V_NULL, + 't' : types.V_TRUE, + '{' : types.V_OBJECT, +} + +func switchRawType(c byte) types.ValueType { + return typeJumpTable[c] +} + +func unwrapError(err error) *Node { + if se, ok := err.(*Node); ok { + return se + }else if sse, ok := err.(Node); ok { + return &sse + } else { + msg := err.Error() + return &Node{ + t: V_ERROR, + v: 0, + p: unsafe.Pointer(&msg), + } + } +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/parser.go b/ihub/vendor/github.com/bytedance/sonic/ast/parser.go new file mode 100644 index 0000000..ebb7bb0 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/parser.go @@ -0,0 +1,618 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + `fmt` + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` +) + +const _DEFAULT_NODE_CAP int = 16 + +const ( + _ERR_NOT_FOUND types.ParsingError = 33 + _ERR_UNSUPPORT_TYPE types.ParsingError = 34 +) + +var ( + ErrNotExist error = newError(_ERR_NOT_FOUND, "value not exists") + ErrUnsupportType error = newError(_ERR_UNSUPPORT_TYPE, "unsupported type") +) + +type Parser struct { + p int + s string + noLazy bool + skipValue bool +} + +/** Parser Private Methods **/ + +func (self *Parser) delim() types.ParsingError { + n := len(self.s) + p := self.lspace(self.p) + + /* check for EOF */ + if p >= n { + return types.ERR_EOF + } + + /* check for the delimtier */ + if self.s[p] != ':' { + return types.ERR_INVALID_CHAR + } + + /* update the read pointer */ + self.p = p + 1 + return 0 +} + +func (self *Parser) object() types.ParsingError { + n := len(self.s) + p := self.lspace(self.p) + + /* check for EOF */ + if p >= n { + return types.ERR_EOF + } + + /* check for the delimtier */ + if self.s[p] != '{' { + return types.ERR_INVALID_CHAR + } + + /* update the read pointer */ + self.p = p + 1 + return 0 +} + +func (self *Parser) array() types.ParsingError { + n := len(self.s) + p := self.lspace(self.p) + + /* check for EOF */ + if p >= n { + return types.ERR_EOF + } + + /* check for the delimtier */ + if self.s[p] != '[' { + return types.ERR_INVALID_CHAR + } + + /* update the read pointer */ + self.p = p + 1 + return 0 +} + +func (self *Parser) lspace(sp int) int { + ns := len(self.s) + for ; sp= ns { + return Node{}, types.ERR_EOF + } + + /* check for empty array */ + if self.s[self.p] == ']' { + self.p++ + return emptyArrayNode, 0 + } + + /* allocate array space and parse every element */ + for { + var val Node + var err types.ParsingError + + if self.skipValue { + /* skip the value */ + var start int + if start, err = self.skipFast(); err != 0 { + return Node{}, err + } + if self.p > ns { + return Node{}, types.ERR_EOF + } + t := switchRawType(self.s[start]) + if t == _V_NONE { + return Node{}, types.ERR_INVALID_CHAR + } + val = newRawNode(self.s[start:self.p], t) + }else{ + /* decode the value */ + if val, err = self.Parse(); err != 0 { + return Node{}, err + } + } + + /* add the value to result */ + ret = append(ret, val) + self.p = self.lspace(self.p) + + /* check for EOF */ + if self.p >= ns { + return Node{}, types.ERR_EOF + } + + /* check for the next character */ + switch self.s[self.p] { + case ',' : self.p++ + case ']' : self.p++; return NewArray(ret), 0 + default: + if val.isLazy() { + return newLazyArray(self, ret), 0 + } + return Node{}, types.ERR_INVALID_CHAR + } + } +} + +func (self *Parser) decodeObject(ret []Pair) (Node, types.ParsingError) { + sp := self.p + ns := len(self.s) + + /* check for EOF */ + if self.p = self.lspace(sp); self.p >= ns { + return Node{}, types.ERR_EOF + } + + /* check for empty object */ + if self.s[self.p] == '}' { + self.p++ + return emptyObjectNode, 0 + } + + /* decode each pair */ + for { + var val Node + var njs types.JsonState + var err types.ParsingError + + /* decode the key */ + if njs = self.decodeValue(); njs.Vt != types.V_STRING { + return Node{}, types.ERR_INVALID_CHAR + } + + /* extract the key */ + idx := self.p - 1 + key := self.s[njs.Iv:idx] + + /* check for escape sequence */ + if njs.Ep != -1 { + if key, err = unquote(key); err != 0 { + return Node{}, err + } + } + + /* expect a ':' delimiter */ + if err = self.delim(); err != 0 { + return Node{}, err + } + + + if self.skipValue { + /* skip the value */ + var start int + if start, err = self.skipFast(); err != 0 { + return Node{}, err + } + if self.p > ns { + return Node{}, types.ERR_EOF + } + t := switchRawType(self.s[start]) + if t == _V_NONE { + return Node{}, types.ERR_INVALID_CHAR + } + val = newRawNode(self.s[start:self.p], t) + } else { + /* decode the value */ + if val, err = self.Parse(); err != 0 { + return Node{}, err + } + } + + /* add the value to result */ + ret = append(ret, Pair{Key: key, Value: val}) + self.p = self.lspace(self.p) + + /* check for EOF */ + if self.p >= ns { + return Node{}, types.ERR_EOF + } + + /* check for the next character */ + switch self.s[self.p] { + case ',' : self.p++ + case '}' : self.p++; return NewObject(ret), 0 + default: + if val.isLazy() { + return newLazyObject(self, ret), 0 + } + return Node{}, types.ERR_INVALID_CHAR + } + } +} + +func (self *Parser) decodeString(iv int64, ep int) (Node, types.ParsingError) { + p := self.p - 1 + s := self.s[iv:p] + + /* fast path: no escape sequence */ + if ep == -1 { + return NewString(s), 0 + } + + /* unquote the string */ + out, err := unquote(s) + + /* check for errors */ + if err != 0 { + return Node{}, err + } else { + return newBytes(rt.Str2Mem(out)), 0 + } +} + +/** Parser Interface **/ + +func (self *Parser) Pos() int { + return self.p +} + +func (self *Parser) Parse() (Node, types.ParsingError) { + switch val := self.decodeValue(); val.Vt { + case types.V_EOF : return Node{}, types.ERR_EOF + case types.V_NULL : return nullNode, 0 + case types.V_TRUE : return trueNode, 0 + case types.V_FALSE : return falseNode, 0 + case types.V_STRING : return self.decodeString(val.Iv, val.Ep) + case types.V_ARRAY: + if self.noLazy { + return self.decodeArray(make([]Node, 0, _DEFAULT_NODE_CAP)) + } + return newLazyArray(self, make([]Node, 0, _DEFAULT_NODE_CAP)), 0 + case types.V_OBJECT: + if self.noLazy { + return self.decodeObject(make([]Pair, 0, _DEFAULT_NODE_CAP)) + } + return newLazyObject(self, make([]Pair, 0, _DEFAULT_NODE_CAP)), 0 + case types.V_DOUBLE : return NewNumber(self.s[val.Ep:self.p]), 0 + case types.V_INTEGER : return NewNumber(self.s[val.Ep:self.p]), 0 + default : return Node{}, types.ParsingError(-val.Vt) + } +} + +func (self *Parser) searchKey(match string) types.ParsingError { + ns := len(self.s) + if err := self.object(); err != 0 { + return err + } + + /* check for EOF */ + if self.p = self.lspace(self.p); self.p >= ns { + return types.ERR_EOF + } + + /* check for empty object */ + if self.s[self.p] == '}' { + self.p++ + return _ERR_NOT_FOUND + } + + var njs types.JsonState + var err types.ParsingError + /* decode each pair */ + for { + + /* decode the key */ + if njs = self.decodeValue(); njs.Vt != types.V_STRING { + return types.ERR_INVALID_CHAR + } + + /* extract the key */ + idx := self.p - 1 + key := self.s[njs.Iv:idx] + + /* check for escape sequence */ + if njs.Ep != -1 { + if key, err = unquote(key); err != 0 { + return err + } + } + + /* expect a ':' delimiter */ + if err = self.delim(); err != 0 { + return err + } + + /* skip value */ + if key != match { + if _, err = self.skip(); err != 0 { + return err + } + } else { + return 0 + } + + /* check for EOF */ + self.p = self.lspace(self.p) + if self.p >= ns { + return types.ERR_EOF + } + + /* check for the next character */ + switch self.s[self.p] { + case ',': + self.p++ + case '}': + self.p++ + return _ERR_NOT_FOUND + default: + return types.ERR_INVALID_CHAR + } + } +} + +func (self *Parser) searchIndex(idx int) types.ParsingError { + ns := len(self.s) + if err := self.array(); err != 0 { + return err + } + + /* check for EOF */ + if self.p = self.lspace(self.p); self.p >= ns { + return types.ERR_EOF + } + + /* check for empty array */ + if self.s[self.p] == ']' { + self.p++ + return _ERR_NOT_FOUND + } + + var err types.ParsingError + /* allocate array space and parse every element */ + for i := 0; i < idx; i++ { + + /* decode the value */ + if _, err = self.skip(); err != 0 { + return err + } + + /* check for EOF */ + self.p = self.lspace(self.p) + if self.p >= ns { + return types.ERR_EOF + } + + /* check for the next character */ + switch self.s[self.p] { + case ',': + self.p++ + case ']': + self.p++ + return _ERR_NOT_FOUND + default: + return types.ERR_INVALID_CHAR + } + } + + return 0 +} + +func (self *Node) skipNextNode() *Node { + if !self.isLazy() { + return nil + } + + parser, stack := self.getParserAndArrayStack() + ret := stack.v + sp := parser.p + ns := len(parser.s) + + /* check for EOF */ + if parser.p = parser.lspace(sp); parser.p >= ns { + return newSyntaxError(parser.syntaxError(types.ERR_EOF)) + } + + /* check for empty array */ + if parser.s[parser.p] == ']' { + parser.p++ + self.setArray(ret) + return nil + } + + var val Node + /* skip the value */ + if start, err := parser.skipFast(); err != 0 { + return newSyntaxError(parser.syntaxError(err)) + } else { + t := switchRawType(parser.s[start]) + if t == _V_NONE { + return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR)) + } + val = newRawNode(parser.s[start:parser.p], t) + } + + /* add the value to result */ + ret = append(ret, val) + parser.p = parser.lspace(parser.p) + + /* check for EOF */ + if parser.p >= ns { + return newSyntaxError(parser.syntaxError(types.ERR_EOF)) + } + + /* check for the next character */ + switch parser.s[parser.p] { + case ',': + parser.p++ + self.setLazyArray(parser, ret) + return &ret[len(ret)-1] + case ']': + parser.p++ + self.setArray(ret) + return &ret[len(ret)-1] + default: + return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR)) + } +} + +func (self *Node) skipNextPair() (*Pair) { + if !self.isLazy() { + return nil + } + + parser, stack := self.getParserAndObjectStack() + ret := stack.v + sp := parser.p + ns := len(parser.s) + + /* check for EOF */ + if parser.p = parser.lspace(sp); parser.p >= ns { + return &Pair{"", *newSyntaxError(parser.syntaxError(types.ERR_EOF))} + } + + /* check for empty object */ + if parser.s[parser.p] == '}' { + parser.p++ + self.setObject(ret) + return nil + } + + /* decode one pair */ + var val Node + var njs types.JsonState + var err types.ParsingError + + /* decode the key */ + if njs = parser.decodeValue(); njs.Vt != types.V_STRING { + return &Pair{"", *newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))} + } + + /* extract the key */ + idx := parser.p - 1 + key := parser.s[njs.Iv:idx] + + /* check for escape sequence */ + if njs.Ep != -1 { + if key, err = unquote(key); err != 0 { + return &Pair{key, *newSyntaxError(parser.syntaxError(err))} + } + } + + /* expect a ':' delimiter */ + if err = parser.delim(); err != 0 { + return &Pair{key, *newSyntaxError(parser.syntaxError(err))} + } + + /* skip the value */ + if start, err := parser.skipFast(); err != 0 { + return &Pair{key, *newSyntaxError(parser.syntaxError(err))} + } else { + t := switchRawType(parser.s[start]) + if t == _V_NONE { + return &Pair{key, *newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))} + } + val = newRawNode(parser.s[start:parser.p], t) + } + + /* add the value to result */ + ret = append(ret, Pair{Key: key, Value: val}) + parser.p = parser.lspace(parser.p) + + /* check for EOF */ + if parser.p >= ns { + return &Pair{key, *newSyntaxError(parser.syntaxError(types.ERR_EOF))} + } + + /* check for the next character */ + switch parser.s[parser.p] { + case ',': + parser.p++ + self.setLazyObject(parser, ret) + return &ret[len(ret)-1] + case '}': + parser.p++ + self.setObject(ret) + return &ret[len(ret)-1] + default: + return &Pair{key, *newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))} + } +} + + +/** Parser Factory **/ + +// Loads parse all json into interface{} +func Loads(src string) (int, interface{}, error) { + ps := &Parser{s: src} + np, err := ps.Parse() + + /* check for errors */ + if err != 0 { + return 0, nil, ps.ExportError(err) + } else { + x, err := np.Interface() + if err != nil { + return 0, nil, err + } + return ps.Pos(), x, nil + } +} + +// LoadsUseNumber parse all json into interface{}, with numeric nodes casted to json.Number +func LoadsUseNumber(src string) (int, interface{}, error) { + ps := &Parser{s: src} + np, err := ps.Parse() + + /* check for errors */ + if err != 0 { + return 0, nil, err + } else { + x, err := np.InterfaceUseNumber() + if err != nil { + return 0, nil, err + } + return ps.Pos(), x, nil + } +} + +func NewParser(src string) *Parser { + return &Parser{s: src} +} + +// ExportError converts types.ParsingError to std Error +func (self *Parser) ExportError(err types.ParsingError) error { + if err == _ERR_NOT_FOUND { + return ErrNotExist + } + return fmt.Errorf("%q", SyntaxError{ + Pos : self.p, + Src : self.s, + Code: err, + }.Description()) +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/search.go b/ihub/vendor/github.com/bytedance/sonic/ast/search.go new file mode 100644 index 0000000..bb6fcea --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/search.go @@ -0,0 +1,30 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +type Searcher struct { + parser Parser +} + +func NewSearcher(str string) *Searcher { + return &Searcher{ + parser: Parser{ + s: str, + noLazy: false, + }, + } +} diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/sort.go b/ihub/vendor/github.com/bytedance/sonic/ast/sort.go new file mode 100644 index 0000000..0a9f145 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/sort.go @@ -0,0 +1,206 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +// Algorithm 3-way Radix Quicksort, d means the radix. +// Reference: https://algs4.cs.princeton.edu/51radix/Quick3string.java.html +func radixQsort(kvs PairSlice, d, maxDepth int) { + for len(kvs) > 11 { + // To avoid the worst case of quickSort (time: O(n^2)), use introsort here. + // Reference: https://en.wikipedia.org/wiki/Introsort and + // https://github.com/golang/go/issues/467 + if maxDepth == 0 { + heapSort(kvs, 0, len(kvs)) + return + } + maxDepth-- + + p := pivot(kvs, d) + lt, i, gt := 0, 0, len(kvs) + for i < gt { + c := byteAt(kvs[i].Key, d) + if c < p { + swap(kvs, lt, i) + i++ + lt++ + } else if c > p { + gt-- + swap(kvs, i, gt) + } else { + i++ + } + } + + // kvs[0:lt] < v = kvs[lt:gt] < kvs[gt:len(kvs)] + // Native implemention: + // radixQsort(kvs[:lt], d, maxDepth) + // if p > -1 { + // radixQsort(kvs[lt:gt], d+1, maxDepth) + // } + // radixQsort(kvs[gt:], d, maxDepth) + // Optimize as follows: make recursive calls only for the smaller parts. + // Reference: https://www.geeksforgeeks.org/quicksort-tail-call-optimization-reducing-worst-case-space-log-n/ + if p == -1 { + if lt > len(kvs) - gt { + radixQsort(kvs[gt:], d, maxDepth) + kvs = kvs[:lt] + } else { + radixQsort(kvs[:lt], d, maxDepth) + kvs = kvs[gt:] + } + } else { + ml := maxThree(lt, gt-lt, len(kvs)-gt) + if ml == lt { + radixQsort(kvs[lt:gt], d+1, maxDepth) + radixQsort(kvs[gt:], d, maxDepth) + kvs = kvs[:lt] + } else if ml == gt-lt { + radixQsort(kvs[:lt], d, maxDepth) + radixQsort(kvs[gt:], d, maxDepth) + kvs = kvs[lt:gt] + d += 1 + } else { + radixQsort(kvs[:lt], d, maxDepth) + radixQsort(kvs[lt:gt], d+1, maxDepth) + kvs = kvs[gt:] + } + } + } + insertRadixSort(kvs, d) +} + +func insertRadixSort(kvs PairSlice, d int) { + for i := 1; i < len(kvs); i++ { + for j := i; j > 0 && lessFrom(kvs[j].Key, kvs[j-1].Key, d); j-- { + swap(kvs, j, j-1) + } + } +} + +func pivot(kvs PairSlice, d int) int { + m := len(kvs) >> 1 + if len(kvs) > 40 { + // Tukey's ``Ninther,'' median of three mediankvs of three. + t := len(kvs) / 8 + return medianThree( + medianThree(byteAt(kvs[0].Key, d), byteAt(kvs[t].Key, d), byteAt(kvs[2*t].Key, d)), + medianThree(byteAt(kvs[m].Key, d), byteAt(kvs[m-t].Key, d), byteAt(kvs[m+t].Key, d)), + medianThree(byteAt(kvs[len(kvs)-1].Key, d), + byteAt(kvs[len(kvs)-1-t].Key, d), + byteAt(kvs[len(kvs)-1-2*t].Key, d))) + } + return medianThree(byteAt(kvs[0].Key, d), byteAt(kvs[m].Key, d), byteAt(kvs[len(kvs)-1].Key, d)) +} + +func medianThree(i, j, k int) int { + if i > j { + i, j = j, i + } // i < j + if k < i { + return i + } + if k > j { + return j + } + return k +} + +func maxThree(i, j, k int) int { + max := i + if max < j { + max = j + } + if max < k { + max = k + } + return max +} + +// maxDepth returns a threshold at which quicksort should switch +// to heapsort. It returnkvs 2*ceil(lg(n+1)). +func maxDepth(n int) int { + var depth int + for i := n; i > 0; i >>= 1 { + depth++ + } + return depth * 2 +} + +// siftDown implements the heap property on kvs[lo:hi]. +// first is an offset into the array where the root of the heap lies. +func siftDown(kvs PairSlice, lo, hi, first int) { + root := lo + for { + child := 2*root + 1 + if child >= hi { + break + } + if child+1 < hi && kvs[first+child].Key < kvs[first+child+1].Key { + child++ + } + if kvs[first+root].Key >= kvs[first+child].Key { + return + } + swap(kvs, first+root, first+child) + root = child + } +} + +func heapSort(kvs PairSlice, a, b int) { + first := a + lo := 0 + hi := b - a + + // Build heap with the greatest element at top. + for i := (hi - 1) / 2; i >= 0; i-- { + siftDown(kvs, i, hi, first) + } + + // Pop elements, the largest first, into end of kvs. + for i := hi - 1; i >= 0; i-- { + swap(kvs, first, first+i) + siftDown(kvs, lo, i, first) + } +} + +// Note that Pair.Key is NOT pointed to Pair.m when map key is integer after swap +func swap(kvs PairSlice, a, b int) { + kvs[a].Key, kvs[b].Key = kvs[b].Key, kvs[a].Key + kvs[a].Value, kvs[b].Value = kvs[b].Value, kvs[a].Value +} + +// Compare two strings from the pos d. +func lessFrom(a, b string, d int) bool { + l := len(a) + if l > len(b) { + l = len(b) + } + for i := d; i < l; i++ { + if a[i] == b[i] { + continue + } + return a[i] < b[i] + } + return len(a) < len(b) +} + +func byteAt(b string, p int) int { + if p < len(b) { + return int(b[p]) + } + return -1 +} diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/stubs_go115.go b/ihub/vendor/github.com/bytedance/sonic/ast/stubs_go115.go new file mode 100644 index 0000000..37b9451 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/stubs_go115.go @@ -0,0 +1,55 @@ +// +build !go1.20 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + `unsafe` + `unicode/utf8` + + `github.com/bytedance/sonic/internal/rt` +) + +//go:noescape +//go:linkname memmove runtime.memmove +//goland:noinspection GoUnusedParameter +func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr) + +//go:linkname unsafe_NewArray reflect.unsafe_NewArray +//goland:noinspection GoUnusedParameter +func unsafe_NewArray(typ *rt.GoType, n int) unsafe.Pointer + +//go:linkname growslice runtime.growslice +//goland:noinspection GoUnusedParameter +func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice + +//go:nosplit +func mem2ptr(s []byte) unsafe.Pointer { + return (*rt.GoSlice)(unsafe.Pointer(&s)).Ptr +} + +var ( + //go:linkname safeSet encoding/json.safeSet + safeSet [utf8.RuneSelf]bool + + //go:linkname hex encoding/json.hex + hex string +) + +//go:linkname unquoteBytes encoding/json.unquoteBytes +func unquoteBytes(s []byte) (t []byte, ok bool) \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/ast/stubs_go120.go b/ihub/vendor/github.com/bytedance/sonic/ast/stubs_go120.go new file mode 100644 index 0000000..bd6fff6 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/ast/stubs_go120.go @@ -0,0 +1,55 @@ +// +build go1.20 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + `unsafe` + `unicode/utf8` + + `github.com/bytedance/sonic/internal/rt` +) + +//go:noescape +//go:linkname memmove runtime.memmove +//goland:noinspection GoUnusedParameter +func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr) + +//go:linkname unsafe_NewArray reflect.unsafe_NewArray +//goland:noinspection GoUnusedParameter +func unsafe_NewArray(typ *rt.GoType, n int) unsafe.Pointer + +//go:linkname growslice reflect.growslice +//goland:noinspection GoUnusedParameter +func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice + +//go:nosplit +func mem2ptr(s []byte) unsafe.Pointer { + return (*rt.GoSlice)(unsafe.Pointer(&s)).Ptr +} + +var ( + //go:linkname safeSet encoding/json.safeSet + safeSet [utf8.RuneSelf]bool + + //go:linkname hex encoding/json.hex + hex string +) + +//go:linkname unquoteBytes encoding/json.unquoteBytes +func unquoteBytes(s []byte) (t []byte, ok bool) \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/bench-arm.sh b/ihub/vendor/github.com/bytedance/sonic/bench-arm.sh new file mode 100644 index 0000000..b47d627 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/bench-arm.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +pwd=$(pwd) +export SONIC_NO_ASYNC_GC=1 + +cd $pwd/ast +go test -benchmem -run=^$ -benchtime=1000000x -bench "^(BenchmarkGet.*|BenchmarkSet.*)$" + +go test -benchmem -run=^$ -benchtime=10000x -bench "^(BenchmarkParser_.*|BenchmarkEncode.*)$" + +go test -benchmem -run=^$ -benchtime=10000000x -bench "^(BenchmarkNodeGetByPath|BenchmarkStructGetByPath|BenchmarkNodeIndex|BenchmarkStructIndex|BenchmarkSliceIndex|BenchmarkMapIndex|BenchmarkNodeGet|BenchmarkSliceGet|BenchmarkMapGet|BenchmarkNodeSet|BenchmarkMapSet|BenchmarkNodeSetByIndex|BenchmarkSliceSetByIndex|BenchmarkStructSetByIndex|BenchmarkNodeUnset|BenchmarkMapUnset|BenchmarkNodUnsetByIndex|BenchmarkSliceUnsetByIndex|BenchmarkNodeAdd|BenchmarkSliceAdd|BenchmarkMapAdd)$" + +unset SONIC_NO_ASYNC_GC +cd $pwd \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/bench-large.png b/ihub/vendor/github.com/bytedance/sonic/bench-large.png new file mode 100644 index 0000000000000000000000000000000000000000..8a8785ec9adce4954f5d507c5e7032ea676907d6 GIT binary patch literal 87463 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

vC;enj&_?Y$AW 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 Giz#Dn{ZL8R^MWW)f)^>9oQz_3H*>-EN-ht*h(P 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%0DtNmsYoJ2}R=PsDSm@K!y}7eB<4Yj@ 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 O9csH&)3zKq{eJ)fqfb@< literal 0 HcmV?d00001 diff --git a/ihub/vendor/github.com/bytedance/sonic/bench.py b/ihub/vendor/github.com/bytedance/sonic/bench.py new file mode 100644 index 0000000..1d4c357 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/bench.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +# Copyright 2022 ByteDance Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import tempfile +import os +import subprocess +import argparse + +gbench_prefix = "SONIC_NO_ASYNC_GC=1 go test -benchmem -run=none " + +def run(cmd): + print(cmd) + if os.system(cmd): + print ("Failed to run cmd: %s"%(cmd)) + exit(1) + +def run_s(cmd): + print (cmd) + try: + res = os.popen(cmd) + except subprocess.CalledProcessError as e: + if e.returncode: + print (e.output) + exit(1) + return res.read() + +def run_r(cmd): + print (cmd) + try: + cmds = cmd.split(' ') + data = subprocess.check_output(cmds, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + if e.returncode: + print (e.output) + exit(1) + return data.decode("utf-8") + +def compare(args): + # detech current branch. + # result = run_r("git branch") + current_branch = run_s("git status | head -n1 | sed 's/On branch //'") + # for br in result.split('\n'): + # if br.startswith("* "): + # current_branch = br.lstrip('* ') + # break + + if not current_branch: + print ("Failed to detech current branch") + return None + + # get the current diff + (fd, diff) = tempfile.mkstemp() + run("git diff > %s"%diff) + + # early return if currrent is main branch. + print ("Current branch: %s"%(current_branch)) + if current_branch == "main": + print ("Cannot compare at the main branch.Please build a new branch") + return None + + # benchmark current branch + (fd, target) = tempfile.mkstemp(".target.txt") + run("%s %s ./... 2>&1 | tee %s" %(gbench_prefix, args, target)) + + # trying to switch to the latest main branch + run("git checkout -- .") + if current_branch != "main": + run("git checkout main") + run("git pull --allow-unrelated-histories origin main") + + # benchmark main branch + (fd, main) = tempfile.mkstemp(".main.txt") + run("%s %s ./... 2>&1 | tee %s" %(gbench_prefix, args, main)) + + # diff the result + # benchstat = "go get golang.org/x/perf/cmd/benchstat && go install golang.org/x/perf/cmd/benchstat" + run( "benchstat -sort=delta %s %s"%(main, target)) + run("git checkout -- .") + + # restore branch + if current_branch != "main": + run("git checkout %s"%(current_branch)) + run("patch -p1 < %s" % (diff)) + return target + +def main(): + argparser = argparse.ArgumentParser(description='Tools to test the performance. Example: ./bench.py -b Decoder_Generic_Sonic -c') + argparser.add_argument('-b', '--bench', dest='filter', required=False, + help='Specify the filter for golang benchmark') + argparser.add_argument('-c', '--compare', dest='compare', action='store_true', required=False, + help='Compare with the main benchmarking') + argparser.add_argument('-t', '--times', dest='times', required=False, + help='benchmark the times') + argparser.add_argument('-r', '--repeat_times', dest='count', required=False, + help='benchmark the count') + args = argparser.parse_args() + + if args.filter: + gbench_args = "-bench=%s"%(args.filter) + else: + gbench_args = "-bench=." + + if args.times: + gbench_args += " -benchtime=%s"%(args.times) + + if args.count: + gbench_args += " -count=%s"%(args.count) + else: + gbench_args += " -count=10" + + if args.compare: + target = compare(gbench_args) + else: + target = None + + if not target: + (fd, target) = tempfile.mkstemp(".target.txt") + run("%s %s ./... 2>&1 | tee %s" %(gbench_prefix, gbench_args, target)) + +if __name__ == "__main__": + main() diff --git a/ihub/vendor/github.com/bytedance/sonic/bench.sh b/ihub/vendor/github.com/bytedance/sonic/bench.sh new file mode 100644 index 0000000..701986b --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/bench.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +pwd=$(pwd) +export SONIC_NO_ASYNC_GC=1 + +cd $pwd/encoder +go test -benchmem -run=^$ -benchtime=100000x -bench "^(BenchmarkEncoder_.*)$" + +cd $pwd/decoder +go test -benchmem -run=^$ -benchtime=100000x -bench "^(BenchmarkDecoder_.*)$" + +cd $pwd/ast +go test -benchmem -run=^$ -benchtime=1000000x -bench "^(BenchmarkGet.*|BenchmarkSet.*)$" + +go test -benchmem -run=^$ -benchtime=10000x -bench "^(BenchmarkParser_.*|BenchmarkEncode.*)$" + +go test -benchmem -run=^$ -benchtime=10000000x -bench "^(BenchmarkNodeGetByPath|BenchmarkStructGetByPath|BenchmarkNodeIndex|BenchmarkStructIndex|BenchmarkSliceIndex|BenchmarkMapIndex|BenchmarkNodeGet|BenchmarkSliceGet|BenchmarkMapGet|BenchmarkNodeSet|BenchmarkMapSet|BenchmarkNodeSetByIndex|BenchmarkSliceSetByIndex|BenchmarkStructSetByIndex|BenchmarkNodeUnset|BenchmarkMapUnset|BenchmarkNodUnsetByIndex|BenchmarkSliceUnsetByIndex|BenchmarkNodeAdd|BenchmarkSliceAdd|BenchmarkMapAdd)$" + +cd $pwd/external_jsonlib_test/benchmark_test +go test -benchmem -run=^$ -benchtime=100000x -bench "^(BenchmarkEncoder_.*|BenchmarkDecoder_.*)$" + +go test -benchmem -run=^$ -benchtime=1000000x -bench "^(BenchmarkGet.*|BenchmarkSet.*)$" + +go test -benchmem -run=^$ -benchtime=10000x -bench "^(BenchmarkParser_.*)$" + +unset SONIC_NO_ASYNC_GC +cd $pwd \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/check_branch_name.sh b/ihub/vendor/github.com/bytedance/sonic/check_branch_name.sh new file mode 100644 index 0000000..d1905da --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/check_branch_name.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +current=$(git status | head -n1 | sed 's/On branch //') +name=${1:-$current} +if [[ ! $name =~ ^(((opt(imize)?|feat(ure)?|doc|(bug|hot)?fix|test|refact(or)?|ci)/.+)|(main|develop)|(release/.+)|(release-v[0-9]+\.[0-9]+)|(release/v[0-9]+\.[0-9]+\.[0-9]+(-[a-z0-9.]+(\+[a-z0-9.]+)?)?)|revert-[a-z0-9]+)$ ]]; then + echo "branch name '$name' is invalid" + exit 1 +else + echo "branch name '$name' is valid" +fi diff --git a/ihub/vendor/github.com/bytedance/sonic/compat.go b/ihub/vendor/github.com/bytedance/sonic/compat.go new file mode 100644 index 0000000..015aa62 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/compat.go @@ -0,0 +1,131 @@ +// +build !amd64 go1.21 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sonic + +import ( + `bytes` + `encoding/json` + `io` + `reflect` + + `github.com/bytedance/sonic/option` +) + +type frozenConfig struct { + Config +} + +// Froze convert the Config to API +func (cfg Config) Froze() API { + api := &frozenConfig{Config: cfg} + return api +} + +func (cfg frozenConfig) marshalOptions(val interface{}, prefix, indent string) ([]byte, error) { + w := bytes.NewBuffer([]byte{}) + enc := json.NewEncoder(w) + enc.SetEscapeHTML(cfg.EscapeHTML) + enc.SetIndent(prefix, indent) + err := enc.Encode(val) + out := w.Bytes() + + // json.Encoder always appends '\n' after encoding, + // which is not same with json.Marshal() + if len(out) > 0 && out[len(out)-1] == '\n' { + out = out[:len(out)-1] + } + return out, err +} + +// Marshal is implemented by sonic +func (cfg frozenConfig) Marshal(val interface{}) ([]byte, error) { + if !cfg.EscapeHTML { + return cfg.marshalOptions(val, "", "") + } + return json.Marshal(val) +} + +// MarshalToString is implemented by sonic +func (cfg frozenConfig) MarshalToString(val interface{}) (string, error) { + out, err := cfg.Marshal(val) + return string(out), err +} + +// MarshalIndent is implemented by sonic +func (cfg frozenConfig) MarshalIndent(val interface{}, prefix, indent string) ([]byte, error) { + if !cfg.EscapeHTML { + return cfg.marshalOptions(val, prefix, indent) + } + return json.MarshalIndent(val, prefix, indent) +} + +// UnmarshalFromString is implemented by sonic +func (cfg frozenConfig) UnmarshalFromString(buf string, val interface{}) error { + r := bytes.NewBufferString(buf) + dec := json.NewDecoder(r) + if cfg.UseNumber { + dec.UseNumber() + } + if cfg.DisallowUnknownFields { + dec.DisallowUnknownFields() + } + return dec.Decode(val) +} + +// Unmarshal is implemented by sonic +func (cfg frozenConfig) Unmarshal(buf []byte, val interface{}) error { + return cfg.UnmarshalFromString(string(buf), val) +} + +// NewEncoder is implemented by sonic +func (cfg frozenConfig) NewEncoder(writer io.Writer) Encoder { + enc := json.NewEncoder(writer) + if !cfg.EscapeHTML { + enc.SetEscapeHTML(cfg.EscapeHTML) + } + return enc +} + +// NewDecoder is implemented by sonic +func (cfg frozenConfig) NewDecoder(reader io.Reader) Decoder { + dec := json.NewDecoder(reader) + if cfg.UseNumber { + dec.UseNumber() + } + if cfg.DisallowUnknownFields { + dec.DisallowUnknownFields() + } + return dec +} + +// Valid is implemented by sonic +func (cfg frozenConfig) Valid(data []byte) bool { + return json.Valid(data) +} + +// Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in +// order to reduce the first-hit latency at **amd64** Arch. +// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is +// a compile option to set the depth of recursive compile for the nested struct type. +// * This is the none implement for !amd64. +// It will be useful for someone who develop with !amd64 arch,like Mac M1. +func Pretouch(vt reflect.Type, opts ...option.CompileOption) error { + return nil +} + diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/asm.s b/ihub/vendor/github.com/bytedance/sonic/decoder/asm.s new file mode 100644 index 0000000..e69de29 diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/assembler_amd64_go116.go b/ihub/vendor/github.com/bytedance/sonic/decoder/assembler_amd64_go116.go new file mode 100644 index 0000000..9ff1ad2 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/assembler_amd64_go116.go @@ -0,0 +1,1943 @@ +// +build go1.15,!go1.17 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `encoding/json` + `fmt` + `math` + `reflect` + `strconv` + `unsafe` + + `github.com/bytedance/sonic/internal/caching` + `github.com/bytedance/sonic/internal/jit` + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` + `github.com/twitchyliquid64/golang-asm/obj` + `github.com/twitchyliquid64/golang-asm/obj/x86` +) + +/** Register Allocations + * + * State Registers: + * + * %rbx : stack base + * %r12 : input pointer + * %r13 : input length + * %r14 : input cursor + * %r15 : value pointer + * + * Error Registers: + * + * %r10 : error type register + * %r11 : error pointer register + */ + +/** Function Prototype & Stack Map + * + * func (s string, ic int, vp unsafe.Pointer, sb *_Stack, fv uint64, sv string) (rc int, err error) + * + * s.buf : (FP) + * s.len : 8(FP) + * ic : 16(FP) + * vp : 24(FP) + * sb : 32(FP) + * fv : 40(FP) + * sv : 56(FP) + * err.vt : 72(FP) + * err.vp : 80(FP) + */ + +const ( + _FP_args = 96 // 96 bytes to pass arguments and return values for this function + _FP_fargs = 80 // 80 bytes for passing arguments to other Go functions + _FP_saves = 40 // 40 bytes for saving the registers before CALL instructions + _FP_locals = 144 // 144 bytes for local variables +) + +const ( + _FP_offs = _FP_fargs + _FP_saves + _FP_locals + _FP_size = _FP_offs + 8 // 8 bytes for the parent frame pointer + _FP_base = _FP_size + 8 // 8 bytes for the return address +) + +const ( + _IM_null = 0x6c6c756e // 'null' + _IM_true = 0x65757274 // 'true' + _IM_alse = 0x65736c61 // 'alse' ('false' without the 'f') +) + +const ( + _BM_space = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n') +) + +const ( + _MODE_JSON = 1 << 3 // base64 mode +) + +const ( + _LB_error = "_error" + _LB_im_error = "_im_error" + _LB_eof_error = "_eof_error" + _LB_type_error = "_type_error" + _LB_field_error = "_field_error" + _LB_range_error = "_range_error" + _LB_stack_error = "_stack_error" + _LB_base64_error = "_base64_error" + _LB_unquote_error = "_unquote_error" + _LB_parsing_error = "_parsing_error" + _LB_parsing_error_v = "_parsing_error_v" + _LB_mismatch_error = "_mismatch_error" +) + +const ( + _LB_char_0_error = "_char_0_error" + _LB_char_1_error = "_char_1_error" + _LB_char_2_error = "_char_2_error" + _LB_char_3_error = "_char_3_error" + _LB_char_4_error = "_char_4_error" + _LB_char_m2_error = "_char_m2_error" + _LB_char_m3_error = "_char_m3_error" +) + +const ( + _LB_skip_one = "_skip_one" + _LB_skip_key_value = "_skip_key_value" +) + +var ( + _AX = jit.Reg("AX") + _CX = jit.Reg("CX") + _DX = jit.Reg("DX") + _DI = jit.Reg("DI") + _SI = jit.Reg("SI") + _BP = jit.Reg("BP") + _SP = jit.Reg("SP") + _R8 = jit.Reg("R8") + _R9 = jit.Reg("R9") + _X0 = jit.Reg("X0") + _X1 = jit.Reg("X1") +) + +var ( + _ST = jit.Reg("BX") + _IP = jit.Reg("R12") + _IL = jit.Reg("R13") + _IC = jit.Reg("R14") + _VP = jit.Reg("R15") +) + +var ( + _R10 = jit.Reg("R10") // used for gcWriteBarrier + _DF = jit.Reg("R10") // reuse R10 in generic decoder for flags + _ET = jit.Reg("R10") + _EP = jit.Reg("R11") +) + +var ( + _ARG_s = _ARG_sp + _ARG_sp = jit.Ptr(_SP, _FP_base) + _ARG_sl = jit.Ptr(_SP, _FP_base + 8) + _ARG_ic = jit.Ptr(_SP, _FP_base + 16) + _ARG_vp = jit.Ptr(_SP, _FP_base + 24) + _ARG_sb = jit.Ptr(_SP, _FP_base + 32) + _ARG_fv = jit.Ptr(_SP, _FP_base + 40) +) + +var ( + _VAR_sv = _VAR_sv_p + _VAR_sv_p = jit.Ptr(_SP, _FP_base + 48) + _VAR_sv_n = jit.Ptr(_SP, _FP_base + 56) + _VAR_vk = jit.Ptr(_SP, _FP_base + 64) +) + +var ( + _RET_rc = jit.Ptr(_SP, _FP_base + 72) + _RET_et = jit.Ptr(_SP, _FP_base + 80) + _RET_ep = jit.Ptr(_SP, _FP_base + 88) +) + +var ( + _VAR_st = _VAR_st_Vt + _VAR_sr = jit.Ptr(_SP, _FP_fargs + _FP_saves) +) + + +var ( + _VAR_st_Vt = jit.Ptr(_SP, _FP_fargs + _FP_saves + 0) + _VAR_st_Dv = jit.Ptr(_SP, _FP_fargs + _FP_saves + 8) + _VAR_st_Iv = jit.Ptr(_SP, _FP_fargs + _FP_saves + 16) + _VAR_st_Ep = jit.Ptr(_SP, _FP_fargs + _FP_saves + 24) + _VAR_st_Db = jit.Ptr(_SP, _FP_fargs + _FP_saves + 32) + _VAR_st_Dc = jit.Ptr(_SP, _FP_fargs + _FP_saves + 40) +) + +var ( + _VAR_ss_AX = jit.Ptr(_SP, _FP_fargs + _FP_saves + 48) + _VAR_ss_CX = jit.Ptr(_SP, _FP_fargs + _FP_saves + 56) + _VAR_ss_SI = jit.Ptr(_SP, _FP_fargs + _FP_saves + 64) + _VAR_ss_R8 = jit.Ptr(_SP, _FP_fargs + _FP_saves + 72) + _VAR_ss_R9 = jit.Ptr(_SP, _FP_fargs + _FP_saves + 80) +) + +var ( + _VAR_bs_p = jit.Ptr(_SP, _FP_fargs + _FP_saves + 88) + _VAR_bs_n = jit.Ptr(_SP, _FP_fargs + _FP_saves + 96) + _VAR_bs_LR = jit.Ptr(_SP, _FP_fargs + _FP_saves + 104) +) + +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_ic = jit.Ptr(_SP, _FP_fargs + _FP_saves + 128) // save dismatched position + _VAR_pc = jit.Ptr(_SP, _FP_fargs + _FP_saves + 136) // save skip return pc +) + +type _Assembler struct { + jit.BaseAssembler + p _Program + name string +} + +func newAssembler(p _Program) *_Assembler { + return new(_Assembler).Init(p) +} + +/** Assembler Interface **/ + +func (self *_Assembler) Load() _Decoder { + return ptodec(self.BaseAssembler.Load("decode_"+self.name, _FP_size, _FP_args, argPtrs, localPtrs)) +} + +func (self *_Assembler) Init(p _Program) *_Assembler { + self.p = p + self.BaseAssembler.Init(self.compile) + return self +} + +func (self *_Assembler) compile() { + self.prologue() + self.instrs() + self.epilogue() + self.copy_string() + self.escape_string() + self.escape_string_twice() + self.skip_one() + self.skip_key_value() + self.mismatch_error() + self.type_error() + self.field_error() + self.range_error() + self.stack_error() + self.base64_error() + self.parsing_error() +} + +/** Assembler Stages **/ + +var _OpFuncTab = [256]func(*_Assembler, *_Instr) { + _OP_any : (*_Assembler)._asm_OP_any, + _OP_dyn : (*_Assembler)._asm_OP_dyn, + _OP_str : (*_Assembler)._asm_OP_str, + _OP_bin : (*_Assembler)._asm_OP_bin, + _OP_bool : (*_Assembler)._asm_OP_bool, + _OP_num : (*_Assembler)._asm_OP_num, + _OP_i8 : (*_Assembler)._asm_OP_i8, + _OP_i16 : (*_Assembler)._asm_OP_i16, + _OP_i32 : (*_Assembler)._asm_OP_i32, + _OP_i64 : (*_Assembler)._asm_OP_i64, + _OP_u8 : (*_Assembler)._asm_OP_u8, + _OP_u16 : (*_Assembler)._asm_OP_u16, + _OP_u32 : (*_Assembler)._asm_OP_u32, + _OP_u64 : (*_Assembler)._asm_OP_u64, + _OP_f32 : (*_Assembler)._asm_OP_f32, + _OP_f64 : (*_Assembler)._asm_OP_f64, + _OP_unquote : (*_Assembler)._asm_OP_unquote, + _OP_nil_1 : (*_Assembler)._asm_OP_nil_1, + _OP_nil_2 : (*_Assembler)._asm_OP_nil_2, + _OP_nil_3 : (*_Assembler)._asm_OP_nil_3, + _OP_deref : (*_Assembler)._asm_OP_deref, + _OP_index : (*_Assembler)._asm_OP_index, + _OP_is_null : (*_Assembler)._asm_OP_is_null, + _OP_is_null_quote : (*_Assembler)._asm_OP_is_null_quote, + _OP_map_init : (*_Assembler)._asm_OP_map_init, + _OP_map_key_i8 : (*_Assembler)._asm_OP_map_key_i8, + _OP_map_key_i16 : (*_Assembler)._asm_OP_map_key_i16, + _OP_map_key_i32 : (*_Assembler)._asm_OP_map_key_i32, + _OP_map_key_i64 : (*_Assembler)._asm_OP_map_key_i64, + _OP_map_key_u8 : (*_Assembler)._asm_OP_map_key_u8, + _OP_map_key_u16 : (*_Assembler)._asm_OP_map_key_u16, + _OP_map_key_u32 : (*_Assembler)._asm_OP_map_key_u32, + _OP_map_key_u64 : (*_Assembler)._asm_OP_map_key_u64, + _OP_map_key_f32 : (*_Assembler)._asm_OP_map_key_f32, + _OP_map_key_f64 : (*_Assembler)._asm_OP_map_key_f64, + _OP_map_key_str : (*_Assembler)._asm_OP_map_key_str, + _OP_map_key_utext : (*_Assembler)._asm_OP_map_key_utext, + _OP_map_key_utext_p : (*_Assembler)._asm_OP_map_key_utext_p, + _OP_array_skip : (*_Assembler)._asm_OP_array_skip, + _OP_array_clear : (*_Assembler)._asm_OP_array_clear, + _OP_array_clear_p : (*_Assembler)._asm_OP_array_clear_p, + _OP_slice_init : (*_Assembler)._asm_OP_slice_init, + _OP_slice_append : (*_Assembler)._asm_OP_slice_append, + _OP_object_skip : (*_Assembler)._asm_OP_object_skip, + _OP_object_next : (*_Assembler)._asm_OP_object_next, + _OP_struct_field : (*_Assembler)._asm_OP_struct_field, + _OP_unmarshal : (*_Assembler)._asm_OP_unmarshal, + _OP_unmarshal_p : (*_Assembler)._asm_OP_unmarshal_p, + _OP_unmarshal_text : (*_Assembler)._asm_OP_unmarshal_text, + _OP_unmarshal_text_p : (*_Assembler)._asm_OP_unmarshal_text_p, + _OP_lspace : (*_Assembler)._asm_OP_lspace, + _OP_match_char : (*_Assembler)._asm_OP_match_char, + _OP_check_char : (*_Assembler)._asm_OP_check_char, + _OP_load : (*_Assembler)._asm_OP_load, + _OP_save : (*_Assembler)._asm_OP_save, + _OP_drop : (*_Assembler)._asm_OP_drop, + _OP_drop_2 : (*_Assembler)._asm_OP_drop_2, + _OP_recurse : (*_Assembler)._asm_OP_recurse, + _OP_goto : (*_Assembler)._asm_OP_goto, + _OP_switch : (*_Assembler)._asm_OP_switch, + _OP_check_char_0 : (*_Assembler)._asm_OP_check_char_0, + _OP_dismatch_err : (*_Assembler)._asm_OP_dismatch_err, + _OP_go_skip : (*_Assembler)._asm_OP_go_skip, + _OP_add : (*_Assembler)._asm_OP_add, +} + +func (self *_Assembler) instr(v *_Instr) { + if fn := _OpFuncTab[v.op()]; fn != nil { + fn(self, v) + } else { + panic(fmt.Sprintf("invalid opcode: %d", v.op())) + } +} + +func (self *_Assembler) instrs() { + for i, v := range self.p { + self.Mark(i) + self.instr(&v) + self.debug_instr(i, &v) + } +} + +func (self *_Assembler) epilogue() { + self.Mark(len(self.p)) + self.Emit("XORL", _EP, _EP) // XORL EP, EP + self.Emit("MOVQ", _VAR_et, _ET) // MOVQ VAR_et, ET + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ", _LB_mismatch_error) // JNZ _LB_mismatch_error + self.Link(_LB_error) // _error: + self.Emit("MOVQ", _IC, _RET_rc) // MOVQ IC, rc<>+40(FP) + self.Emit("MOVQ", _ET, _RET_et) // MOVQ ET, et<>+48(FP) + self.Emit("MOVQ", _EP, _RET_ep) // MOVQ EP, ep<>+56(FP) + self.Emit("MOVQ", jit.Ptr(_SP, _FP_offs), _BP) // MOVQ _FP_offs(SP), BP + self.Emit("ADDQ", jit.Imm(_FP_size), _SP) // ADDQ $_FP_size, SP + self.Emit("RET") // RET +} + +func (self *_Assembler) prologue() { + self.Emit("SUBQ", jit.Imm(_FP_size), _SP) // SUBQ $_FP_size, SP + self.Emit("MOVQ", _BP, jit.Ptr(_SP, _FP_offs)) // MOVQ BP, _FP_offs(SP) + self.Emit("LEAQ", jit.Ptr(_SP, _FP_offs), _BP) // LEAQ _FP_offs(SP), BP + self.Emit("MOVQ", _ARG_sp, _IP) // MOVQ s.p<>+0(FP), IP + self.Emit("MOVQ", _ARG_sl, _IL) // MOVQ s.l<>+8(FP), IL + self.Emit("MOVQ", _ARG_ic, _IC) // MOVQ ic<>+16(FP), IC + self.Emit("MOVQ", _ARG_vp, _VP) // MOVQ vp<>+24(FP), VP + self.Emit("MOVQ", _ARG_sb, _ST) // MOVQ vp<>+32(FP), ST + // initialize digital buffer first + self.Emit("MOVQ", jit.Imm(_MaxDigitNums), _VAR_st_Dc) // MOVQ $_MaxDigitNums, ss.Dcap + self.Emit("LEAQ", jit.Ptr(_ST, _DbufOffset), _AX) // LEAQ _DbufOffset(ST), AX + self.Emit("MOVQ", _AX, _VAR_st_Db) // MOVQ AX, ss.Dbuf + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("MOVQ", _AX, _VAR_et) // MOVQ AX, ss.Dp +} + +/** Function Calling Helpers **/ + +var _REG_go = []obj.Addr { + _ST, + _VP, + _IP, + _IL, + _IC, +} + +func (self *_Assembler) save(r ...obj.Addr) { + for i, v := range r { + if i > _FP_saves / 8 - 1 { + panic("too many registers to save") + } else { + self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs + int64(i) * 8)) + } + } +} + +func (self *_Assembler) load(r ...obj.Addr) { + for i, v := range r { + if i > _FP_saves / 8 - 1 { + panic("too many registers to load") + } else { + self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs + int64(i) * 8), v) + } + } +} + +func (self *_Assembler) call(fn obj.Addr) { + self.Emit("MOVQ", fn, _AX) // MOVQ ${fn}, AX + self.Rjmp("CALL", _AX) // CALL AX +} + +func (self *_Assembler) call_go(fn obj.Addr) { + self.save(_REG_go...) // SAVE $REG_go + self.call(fn) // CALL ${fn} + self.load(_REG_go...) // LOAD $REG_go +} + +func (self *_Assembler) call_sf(fn obj.Addr) { + self.Emit("LEAQ", _ARG_s, _DI) // LEAQ s<>+0(FP), DI + self.Emit("MOVQ", _IC, _ARG_ic) // MOVQ IC, ic<>+16(FP) + self.Emit("LEAQ", _ARG_ic, _SI) // LEAQ ic<>+16(FP), SI + self.Emit("LEAQ", jit.Ptr(_ST, _FsmOffset), _DX) // LEAQ _FsmOffset(ST), DX + self.Emit("MOVQ", _ARG_fv, _CX) + self.call(fn) // CALL ${fn} + self.Emit("MOVQ", _ARG_ic, _IC) // MOVQ ic<>+16(FP), IC +} + +func (self *_Assembler) call_vf(fn obj.Addr) { + self.Emit("LEAQ", _ARG_s, _DI) // LEAQ s<>+0(FP), DI + self.Emit("MOVQ", _IC, _ARG_ic) // MOVQ IC, ic<>+16(FP) + self.Emit("LEAQ", _ARG_ic, _SI) // LEAQ ic<>+16(FP), SI + self.Emit("LEAQ", _VAR_st, _DX) // LEAQ st, DX + self.call(fn) // CALL ${fn} + self.Emit("MOVQ", _ARG_ic, _IC) // MOVQ ic<>+16(FP), IC +} + +/** Assembler Error Handlers **/ + +var ( + _F_convT64 = jit.Func(convT64) + _F_error_wrap = jit.Func(error_wrap) + _F_error_type = jit.Func(error_type) + _F_error_field = jit.Func(error_field) + _F_error_value = jit.Func(error_value) + _F_error_mismatch = jit.Func(error_mismatch) +) + +var ( + _I_int8 , _T_int8 = rtype(reflect.TypeOf(int8(0))) + _I_int16 , _T_int16 = rtype(reflect.TypeOf(int16(0))) + _I_int32 , _T_int32 = rtype(reflect.TypeOf(int32(0))) + _I_uint8 , _T_uint8 = rtype(reflect.TypeOf(uint8(0))) + _I_uint16 , _T_uint16 = rtype(reflect.TypeOf(uint16(0))) + _I_uint32 , _T_uint32 = rtype(reflect.TypeOf(uint32(0))) + _I_float32 , _T_float32 = rtype(reflect.TypeOf(float32(0))) +) + +var ( + _T_error = rt.UnpackType(errorType) + _I_base64_CorruptInputError = jit.Itab(_T_error, base64CorruptInputError) +) + +var ( + _V_stackOverflow = jit.Imm(int64(uintptr(unsafe.Pointer(&stackOverflow)))) + _I_json_UnsupportedValueError = jit.Itab(_T_error, reflect.TypeOf(new(json.UnsupportedValueError))) +) + +func (self *_Assembler) type_error() { + self.Link(_LB_type_error) // _type_error: + self.Emit("MOVQ", _ET, jit.Ptr(_SP, 0)) // MOVQ ET, (SP) + self.call_go(_F_error_type) // CALL_GO error_type + self.Emit("MOVQ", jit.Ptr(_SP, 8), _ET) // MOVQ 8(SP), ET + self.Emit("MOVQ", jit.Ptr(_SP, 16), _EP) // MOVQ 16(SP), EP + self.Sjmp("JMP" , _LB_error) // JMP _error +} + + +func (self *_Assembler) mismatch_error() { + self.Link(_LB_mismatch_error) // _type_error: + self.Emit("MOVQ", _ARG_sp, _AX) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ", _ARG_sl, _CX) + self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP) + self.Emit("MOVQ", _VAR_ic, _AX) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16)) // MOVQ AX, 16(SP) + self.Emit("MOVQ", _VAR_et, _CX) + self.Emit("MOVQ", _CX, jit.Ptr(_SP, 24)) // MOVQ CX, 24(SP) + self.call_go(_F_error_mismatch) // CALL_GO error_type + self.Emit("MOVQ", jit.Ptr(_SP, 32), _ET) // MOVQ 32(SP), ET + self.Emit("MOVQ", jit.Ptr(_SP, 40), _EP) // MOVQ 40(SP), EP + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) _asm_OP_dismatch_err(p *_Instr) { + self.Emit("MOVQ", _IC, _VAR_ic) + self.Emit("MOVQ", jit.Type(p.vt()), _ET) + self.Emit("MOVQ", _ET, _VAR_et) +} + +func (self *_Assembler) _asm_OP_go_skip(p *_Instr) { + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Xref(p.vi(), 4) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_one) // JMP _skip_one +} + +func (self *_Assembler) skip_one() { + self.Link(_LB_skip_one) // _skip: + self.Emit("MOVQ", _VAR_ic, _IC) // MOVQ _VAR_ic, IC + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v + self.Emit("MOVQ" , _VAR_pc, _R9) // MOVQ pc, R9 + self.Rjmp("JMP" , _R9) // JMP (R9) +} + + +func (self *_Assembler) skip_key_value() { + self.Link(_LB_skip_key_value) // _skip: + // skip the key + self.Emit("MOVQ", _VAR_ic, _IC) // MOVQ _VAR_ic, IC + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v + // match char ':' + self.lspace("_global_1") + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(':')) + self.Sjmp("JNE" , _LB_parsing_error_v) // JNE _parse_error_v + self.Emit("ADDQ", jit.Imm(1), _IC) // ADDQ $1, IC + self.lspace("_global_2") + // skip the value + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v + // jump back to specified address + self.Emit("MOVQ" , _VAR_pc, _R9) // MOVQ pc, R9 + self.Rjmp("JMP" , _R9) // JMP (R9) +} + +func (self *_Assembler) field_error() { + self.Link(_LB_field_error) // _field_error: + self.Emit("MOVOU", _VAR_sv, _X0) // MOVOU sv, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 0)) // MOVOU X0, (SP) + self.call_go(_F_error_field) // CALL_GO error_field + self.Emit("MOVQ" , jit.Ptr(_SP, 16), _ET) // MOVQ 16(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 24), _EP) // MOVQ 24(SP), EP + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) range_error() { + self.Link(_LB_range_error) // _range_error: + self.slice_from(_VAR_st_Ep, 0) // SLICE st.Ep, $0 + self.Emit("MOVQ", _DI, jit.Ptr(_SP, 0)) // MOVQ DI, (SP) + self.Emit("MOVQ", _SI, jit.Ptr(_SP, 8)) // MOVQ SI, 8(SP) + self.Emit("MOVQ", _ET, jit.Ptr(_SP, 16)) // MOVQ ET, 16(SP) + self.Emit("MOVQ", _EP, jit.Ptr(_SP, 24)) // MOVQ EP, 24(SP) + self.call_go(_F_error_value) // CALL_GO error_value + self.Emit("MOVQ", jit.Ptr(_SP, 32), _ET) // MOVQ 32(SP), ET + self.Emit("MOVQ", jit.Ptr(_SP, 40), _EP) // MOVQ 40(SP), EP + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) stack_error() { + self.Link(_LB_stack_error) // _stack_error: + self.Emit("MOVQ", _V_stackOverflow, _EP) // MOVQ ${_V_stackOverflow}, EP + self.Emit("MOVQ", _I_json_UnsupportedValueError, _ET) // MOVQ ${_I_json_UnsupportedValueError}, ET + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) base64_error() { + self.Link(_LB_base64_error) + self.Emit("NEGQ", _AX) // NEGQ AX + self.Emit("SUBQ", jit.Imm(1), _AX) // SUBQ $1, AX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.call_go(_F_convT64) // CALL_GO convT64 + self.Emit("MOVQ", jit.Ptr(_SP, 8), _EP) // MOVQ 8(SP), EP + self.Emit("MOVQ", _I_base64_CorruptInputError, _ET) // MOVQ ${itab(base64.CorruptInputError)}, ET + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) parsing_error() { + self.Link(_LB_eof_error) // _eof_error: + self.Emit("MOVQ" , _IL, _IC) // MOVQ IL, IC + self.Emit("MOVL" , jit.Imm(int64(types.ERR_EOF)), _EP) // MOVL ${types.ERR_EOF}, EP + self.Sjmp("JMP" , _LB_parsing_error) // JMP _parsing_error + self.Link(_LB_unquote_error) // _unquote_error: + self.Emit("SUBQ" , _VAR_sr, _SI) // SUBQ sr, SI + self.Emit("SUBQ" , _SI, _IC) // SUBQ IL, IC + self.Link(_LB_parsing_error_v) // _parsing_error_v: + self.Emit("MOVQ" , _AX, _EP) // MOVQ AX, EP + self.Emit("NEGQ" , _EP) // NEGQ EP + self.Sjmp("JMP" , _LB_parsing_error) // JMP _parsing_error + self.Link(_LB_char_m3_error) // _char_m3_error: + self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC + self.Link(_LB_char_m2_error) // _char_m2_error: + self.Emit("SUBQ" , jit.Imm(2), _IC) // SUBQ $2, IC + self.Sjmp("JMP" , _LB_char_0_error) // JMP _char_0_error + self.Link(_LB_im_error) // _im_error: + self.Emit("CMPB" , _CX, jit.Sib(_IP, _IC, 1, 0)) // CMPB CX, (IP)(IC) + self.Sjmp("JNE" , _LB_char_0_error) // JNE _char_0_error + self.Emit("SHRL" , jit.Imm(8), _CX) // SHRL $8, CX + self.Emit("CMPB" , _CX, jit.Sib(_IP, _IC, 1, 1)) // CMPB CX, 1(IP)(IC) + self.Sjmp("JNE" , _LB_char_1_error) // JNE _char_1_error + self.Emit("SHRL" , jit.Imm(8), _CX) // SHRL $8, CX + self.Emit("CMPB" , _CX, jit.Sib(_IP, _IC, 1, 2)) // CMPB CX, 2(IP)(IC) + self.Sjmp("JNE" , _LB_char_2_error) // JNE _char_2_error + self.Sjmp("JMP" , _LB_char_3_error) // JNE _char_3_error + self.Link(_LB_char_4_error) // _char_4_error: + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Link(_LB_char_3_error) // _char_3_error: + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Link(_LB_char_2_error) // _char_2_error: + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Link(_LB_char_1_error) // _char_1_error: + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Link(_LB_char_0_error) // _char_0_error: + self.Emit("MOVL" , jit.Imm(int64(types.ERR_INVALID_CHAR)), _EP) // MOVL ${types.ERR_INVALID_CHAR}, EP + self.Link(_LB_parsing_error) // _parsing_error: + self.Emit("MOVOU", _ARG_s, _X0) // MOVOU s, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 0)) // MOVOU X0, (SP) + self.Emit("MOVQ" , _IC, jit.Ptr(_SP, 16)) // MOVQ IC, 16(SP) + self.Emit("MOVQ" , _EP, jit.Ptr(_SP, 24)) // MOVQ EP, 24(SP) + self.call_go(_F_error_wrap) // CALL_GO error_wrap + self.Emit("MOVQ" , jit.Ptr(_SP, 32), _ET) // MOVQ 32(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _EP) // MOVQ 40(SP), EP + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +/** Memory Management Routines **/ + +var ( + _T_byte = jit.Type(byteType) + _F_mallocgc = jit.Func(mallocgc) +) + +func (self *_Assembler) malloc(nb obj.Addr, ret obj.Addr) { + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("MOVQ", _T_byte, _CX) // MOVQ ${type(byte)}, CX + self.Emit("MOVQ", nb, jit.Ptr(_SP, 0)) // MOVQ ${nb}, (SP) + self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16)) // MOVQ AX, 16(SP) + self.call_go(_F_mallocgc) // CALL_GO mallocgc + self.Emit("MOVQ", jit.Ptr(_SP, 24), ret) // MOVQ 24(SP), ${ret} +} + +func (self *_Assembler) valloc(vt reflect.Type, ret obj.Addr) { + self.Emit("MOVQ", jit.Imm(int64(vt.Size())), _AX) // MOVQ ${vt.Size()}, AX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ", jit.Type(vt), _AX) // MOVQ ${vt}, AX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) + self.Emit("MOVB", jit.Imm(1), jit.Ptr(_SP, 16)) // MOVB $1, 16(SP) + self.call_go(_F_mallocgc) // CALL_GO mallocgc + self.Emit("MOVQ", jit.Ptr(_SP, 24), ret) // MOVQ 24(SP), ${ret} +} + +func (self *_Assembler) vfollow(vt reflect.Type) { + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _AX) // MOVQ (VP), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNZ" , "_end_{n}") // JNZ _end_{n} + self.valloc(vt, _AX) // VALLOC ${vt}, AX + self.WritePtrAX(1, jit.Ptr(_VP, 0), false) // MOVQ AX, (VP) + self.Link("_end_{n}") // _end_{n}: + self.Emit("MOVQ" , _AX, _VP) // MOVQ AX, VP +} + +/** Value Parsing Routines **/ + +var ( + _F_vstring = jit.Imm(int64(native.S_vstring)) + _F_vnumber = jit.Imm(int64(native.S_vnumber)) + _F_vsigned = jit.Imm(int64(native.S_vsigned)) + _F_vunsigned = jit.Imm(int64(native.S_vunsigned)) +) + +func (self *_Assembler) check_err(vt reflect.Type, pin string, pin2 int) { + self.Emit("MOVQ" , _VAR_st_Vt, _AX) // MOVQ st.Vt, AX + self.Emit("TESTQ", _AX, _AX) // CMPQ AX, ${native.V_STRING} + // try to skip the value + if vt != nil { + self.Sjmp("JNS" , "_check_err_{n}") // JNE _parsing_error_v + self.Emit("MOVQ", jit.Type(vt), _ET) + self.Emit("MOVQ", _ET, _VAR_et) + if pin2 != -1 { + self.Emit("SUBQ", jit.Imm(1), _BP) + self.Emit("MOVQ", _BP, _VAR_ic) + self.Byte(0x4c , 0x8d, 0x0d) // LEAQ (PC), R9 + self.Xref(pin2, 4) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_key_value) + } else { + self.Emit("MOVQ", _BP, _VAR_ic) + self.Byte(0x4c , 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref(pin, 4) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_one) + } + self.Link("_check_err_{n}") + } else { + self.Sjmp("JS" , _LB_parsing_error_v) // JNE _parsing_error_v + } +} + +func (self *_Assembler) check_eof(d int64) { + if d == 1 { + self.Emit("CMPQ", _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , _LB_eof_error) // JAE _eof_error + } else { + self.Emit("LEAQ", jit.Ptr(_IC, d), _AX) // LEAQ ${d}(IC), AX + self.Emit("CMPQ", _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , _LB_eof_error) // JA _eof_error + } +} + +func (self *_Assembler) parse_string() { // parse_string has a validate flag params in the last + self.Emit("MOVQ", _ARG_fv, _CX) + self.call_vf(_F_vstring) + self.check_err(nil, "", -1) +} + +func (self *_Assembler) parse_number(vt reflect.Type, pin string, pin2 int) { + self.Emit("MOVQ", _IC, _BP) + self.call_vf(_F_vnumber) // call vnumber + self.check_err(vt, pin, pin2) +} + +func (self *_Assembler) parse_signed(vt reflect.Type, pin string, pin2 int) { + self.Emit("MOVQ", _IC, _BP) + self.call_vf(_F_vsigned) + self.check_err(vt, pin, pin2) +} + +func (self *_Assembler) parse_unsigned(vt reflect.Type, pin string, pin2 int) { + self.Emit("MOVQ", _IC, _BP) + self.call_vf(_F_vunsigned) + self.check_err(vt, pin, pin2) +} + +// Pointer: DI, Size: SI, Return: R9 +func (self *_Assembler) copy_string() { + self.Link("_copy_string") + self.Emit("MOVQ", _DI, _VAR_bs_p) + self.Emit("MOVQ", _SI, _VAR_bs_n) + self.Emit("MOVQ", _R9, _VAR_bs_LR) + self.malloc(_SI, _AX) + self.Emit("MOVQ", _AX, _VAR_sv_p) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) + self.Emit("MOVQ", _VAR_bs_p, _DI) + self.Emit("MOVQ", _DI, jit.Ptr(_SP, 8)) + self.Emit("MOVQ", _VAR_bs_n, _SI) + self.Emit("MOVQ", _SI, jit.Ptr(_SP, 16)) + self.call_go(_F_memmove) + self.Emit("MOVQ", _VAR_sv_p, _DI) + self.Emit("MOVQ", _VAR_bs_n, _SI) + self.Emit("MOVQ", _VAR_bs_LR, _R9) + self.Rjmp("JMP", _R9) +} + +// Pointer: DI, Size: SI, Return: R9 +func (self *_Assembler) escape_string() { + self.Link("_escape_string") + self.Emit("MOVQ" , _DI, _VAR_bs_p) + self.Emit("MOVQ" , _SI, _VAR_bs_n) + self.Emit("MOVQ" , _R9, _VAR_bs_LR) + self.malloc(_SI, _DX) // MALLOC SI, DX + self.Emit("MOVQ" , _DX, _VAR_sv_p) + self.Emit("MOVQ" , _VAR_bs_p, _DI) + self.Emit("MOVQ" , _VAR_bs_n, _SI) + self.Emit("LEAQ" , _VAR_sr, _CX) // LEAQ sr, CX + self.Emit("XORL" , _R8, _R8) // XORL R8, R8 + self.Emit("BTQ" , jit.Imm(_F_disable_urc), _ARG_fv) // BTQ ${_F_disable_urc}, fv + self.Emit("SETCC", _R8) // SETCC R8 + self.Emit("SHLQ" , jit.Imm(types.B_UNICODE_REPLACE), _R8) // SHLQ ${types.B_UNICODE_REPLACE}, R8 + self.call(_F_unquote) // CALL unquote + self.Emit("MOVQ" , _VAR_bs_n, _SI) // MOVQ ${n}, SI + self.Emit("ADDQ" , jit.Imm(1), _SI) // ADDQ $1, SI + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_unquote_error) // JS _unquote_error + self.Emit("MOVQ" , _AX, _SI) + self.Emit("MOVQ" , _VAR_sv_p, _DI) + self.Emit("MOVQ" , _VAR_bs_LR, _R9) + self.Rjmp("JMP", _R9) +} + +func (self *_Assembler) escape_string_twice() { + self.Link("_escape_string_twice") + self.Emit("MOVQ" , _DI, _VAR_bs_p) + self.Emit("MOVQ" , _SI, _VAR_bs_n) + self.Emit("MOVQ" , _R9, _VAR_bs_LR) + self.malloc(_SI, _DX) // MALLOC SI, DX + self.Emit("MOVQ" , _DX, _VAR_sv_p) + self.Emit("MOVQ" , _VAR_bs_p, _DI) + self.Emit("MOVQ" , _VAR_bs_n, _SI) + self.Emit("LEAQ" , _VAR_sr, _CX) // LEAQ sr, CX + self.Emit("MOVL" , jit.Imm(types.F_DOUBLE_UNQUOTE), _R8) // MOVL ${types.F_DOUBLE_UNQUOTE}, R8 + self.Emit("BTQ" , jit.Imm(_F_disable_urc), _ARG_fv) // BTQ ${_F_disable_urc}, AX + self.Emit("XORL" , _AX, _AX) // XORL AX, AX + self.Emit("SETCC", _AX) // SETCC AX + self.Emit("SHLQ" , jit.Imm(types.B_UNICODE_REPLACE), _AX) // SHLQ ${types.B_UNICODE_REPLACE}, AX + self.Emit("ORQ" , _AX, _R8) // ORQ AX, R8 + self.call(_F_unquote) // CALL unquote + self.Emit("MOVQ" , _VAR_bs_n, _SI) // MOVQ ${n}, SI + self.Emit("ADDQ" , jit.Imm(3), _SI) // ADDQ $3, SI + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_unquote_error) // JS _unquote_error + self.Emit("MOVQ" , _AX, _SI) + self.Emit("MOVQ" , _VAR_sv_p, _DI) + self.Emit("MOVQ" , _VAR_bs_LR, _R9) + self.Rjmp("JMP", _R9) +} + +/** Range Checking Routines **/ + +var ( + _V_max_f32 = jit.Imm(int64(uintptr(unsafe.Pointer(_Vp_max_f32)))) + _V_min_f32 = jit.Imm(int64(uintptr(unsafe.Pointer(_Vp_min_f32)))) +) + +var ( + _Vp_max_f32 = new(float64) + _Vp_min_f32 = new(float64) +) + +func init() { + *_Vp_max_f32 = math.MaxFloat32 + *_Vp_min_f32 = -math.MaxFloat32 +} + +func (self *_Assembler) range_single() { + self.Emit("MOVSD" , _VAR_st_Dv, _X0) // MOVSD st.Dv, X0 + self.Emit("MOVQ" , _V_max_f32, _AX) // MOVQ _max_f32, AX + self.Emit("MOVQ" , jit.Gitab(_I_float32), _ET) // MOVQ ${itab(float32)}, ET + self.Emit("MOVQ" , jit.Gtype(_T_float32), _EP) // MOVQ ${type(float32)}, EP + self.Emit("UCOMISD" , jit.Ptr(_AX, 0), _X0) // UCOMISD (AX), X0 + self.Sjmp("JA" , _LB_range_error) // JA _range_error + self.Emit("MOVQ" , _V_min_f32, _AX) // MOVQ _min_f32, AX + self.Emit("MOVSD" , jit.Ptr(_AX, 0), _X1) // MOVSD (AX), X1 + self.Emit("UCOMISD" , _X0, _X1) // UCOMISD X0, X1 + self.Sjmp("JA" , _LB_range_error) // JA _range_error + self.Emit("CVTSD2SS", _X0, _X0) // CVTSD2SS X0, X0 +} + +func (self *_Assembler) range_signed(i *rt.GoItab, t *rt.GoType, a int64, b int64) { + self.Emit("MOVQ", _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.Emit("MOVQ", jit.Gitab(i), _ET) // MOVQ ${i}, ET + self.Emit("MOVQ", jit.Gtype(t), _EP) // MOVQ ${t}, EP + self.Emit("CMPQ", _AX, jit.Imm(a)) // CMPQ AX, ${a} + self.Sjmp("JL" , _LB_range_error) // JL _range_error + self.Emit("CMPQ", _AX, jit.Imm(b)) // CMPQ AX, ${B} + self.Sjmp("JG" , _LB_range_error) // JG _range_error +} + +func (self *_Assembler) range_unsigned(i *rt.GoItab, t *rt.GoType, v uint64) { + self.Emit("MOVQ" , _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.Emit("MOVQ" , jit.Gitab(i), _ET) // MOVQ ${i}, ET + self.Emit("MOVQ" , jit.Gtype(t), _EP) // MOVQ ${t}, EP + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_range_error) // JS _range_error + self.Emit("CMPQ" , _AX, jit.Imm(int64(v))) // CMPQ AX, ${a} + self.Sjmp("JA" , _LB_range_error) // JA _range_error +} + +/** String Manipulating Routines **/ + +var ( + _F_unquote = jit.Imm(int64(native.S_unquote)) +) + +func (self *_Assembler) slice_from(p obj.Addr, d int64) { + self.Emit("MOVQ", p, _SI) // MOVQ ${p}, SI + self.slice_from_r(_SI, d) // SLICE_R SI, ${d} +} + +func (self *_Assembler) slice_from_r(p obj.Addr, d int64) { + self.Emit("LEAQ", jit.Sib(_IP, p, 1, 0), _DI) // LEAQ (IP)(${p}), DI + self.Emit("NEGQ", p) // NEGQ ${p} + self.Emit("LEAQ", jit.Sib(_IC, p, 1, d), _SI) // LEAQ d(IC)(${p}), SI +} + +func (self *_Assembler) unquote_once(p obj.Addr, n obj.Addr, stack bool, copy bool) { + self.slice_from(_VAR_st_Iv, -1) // SLICE st.Iv, $-1 + self.Emit("CMPQ" , _VAR_st_Ep, jit.Imm(-1)) // CMPQ st.Ep, $-1 + self.Sjmp("JE" , "_noescape_{n}") // JE _noescape_{n} + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_unquote_once_write_{n}", 4) + self.Sjmp("JMP" , "_escape_string") + self.Link("_noescape_{n}") // _noescape_{n}: + if copy { + self.Emit("BTQ" , jit.Imm(_F_copy_string), _ARG_fv) + self.Sjmp("JNC", "_unquote_once_write_{n}") + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_unquote_once_write_{n}", 4) + self.Sjmp("JMP", "_copy_string") + } + self.Link("_unquote_once_write_{n}") + self.Emit("MOVQ" , _SI, n) // MOVQ SI, ${n} + if stack { + self.Emit("MOVQ", _DI, p) + } else { + self.WriteRecNotAX(10, _DI, p, false, false) + } +} + +func (self *_Assembler) unquote_twice(p obj.Addr, n obj.Addr, stack bool) { + self.Emit("CMPQ" , _VAR_st_Ep, jit.Imm(-1)) // CMPQ st.Ep, $-1 + self.Sjmp("JE" , _LB_eof_error) // JE _eof_error + self.Emit("CMPB" , jit.Sib(_IP, _IC, 1, -3), jit.Imm('\\')) // CMPB -3(IP)(IC), $'\\' + self.Sjmp("JNE" , _LB_char_m3_error) // JNE _char_m3_error + self.Emit("CMPB" , jit.Sib(_IP, _IC, 1, -2), jit.Imm('"')) // CMPB -2(IP)(IC), $'"' + self.Sjmp("JNE" , _LB_char_m2_error) // JNE _char_m2_error + self.slice_from(_VAR_st_Iv, -3) // SLICE st.Iv, $-3 + self.Emit("MOVQ" , _SI, _AX) // MOVQ SI, AX + self.Emit("ADDQ" , _VAR_st_Iv, _AX) // ADDQ st.Iv, AX + self.Emit("CMPQ" , _VAR_st_Ep, _AX) // CMPQ st.Ep, AX + self.Sjmp("JE" , "_noescape_{n}") // JE _noescape_{n} + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_unquote_twice_write_{n}", 4) + self.Sjmp("JMP" , "_escape_string_twice") + self.Link("_noescape_{n}") // _noescape_{n}: + self.Emit("BTQ" , jit.Imm(_F_copy_string), _ARG_fv) + self.Sjmp("JNC", "_unquote_twice_write_{n}") + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_unquote_twice_write_{n}", 4) + self.Sjmp("JMP", "_copy_string") + self.Link("_unquote_twice_write_{n}") + self.Emit("MOVQ" , _SI, n) // MOVQ SI, ${n} + if stack { + self.Emit("MOVQ", _DI, p) + } else { + self.WriteRecNotAX(12, _DI, p, false, false) + } +} + +/** Memory Clearing Routines **/ + +var ( + _F_memclrHasPointers = jit.Func(memclrHasPointers) + _F_memclrNoHeapPointers = jit.Func(memclrNoHeapPointers) +) + +func (self *_Assembler) mem_clear_fn(ptrfree bool) { + if !ptrfree { + self.call_go(_F_memclrHasPointers) + } else { + self.call_go(_F_memclrNoHeapPointers) + } +} + +func (self *_Assembler) mem_clear_rem(size int64, ptrfree bool) { + self.Emit("MOVQ", jit.Imm(size), _CX) // MOVQ ${size}, CX + self.Emit("MOVQ", jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, 0), _AX) // MOVQ (ST)(AX), AX + self.Emit("SUBQ", _VP, _AX) // SUBQ VP, AX + self.Emit("ADDQ", _AX, _CX) // ADDQ AX, CX + self.Emit("MOVQ", _VP, jit.Ptr(_SP, 0)) // MOVQ VP, (SP) + self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP) + self.mem_clear_fn(ptrfree) // CALL_GO memclr{Has,NoHeap}Pointers +} + +/** Map Assigning Routines **/ + +var ( + _F_mapassign = jit.Func(mapassign) + _F_mapassign_fast32 = jit.Func(mapassign_fast32) + _F_mapassign_faststr = jit.Func(mapassign_faststr) + _F_mapassign_fast64ptr = jit.Func(mapassign_fast64ptr) +) + +var ( + _F_decodeJsonUnmarshaler obj.Addr + _F_decodeTextUnmarshaler obj.Addr +) + +func init() { + _F_decodeJsonUnmarshaler = jit.Func(decodeJsonUnmarshaler) + _F_decodeTextUnmarshaler = jit.Func(decodeTextUnmarshaler) +} + +func (self *_Assembler) mapaccess_ptr(t reflect.Type) { + if rt.MapType(rt.UnpackType(t)).IndirectElem() { + self.vfollow(t.Elem()) + } +} + +func (self *_Assembler) mapassign_std(t reflect.Type, v obj.Addr) { + self.Emit("LEAQ", v, _AX) // LEAQ ${v}, AX + self.mapassign_call(t, _F_mapassign) // MAPASSIGN ${t}, mapassign +} + +func (self *_Assembler) mapassign_str_fast(t reflect.Type, p obj.Addr, n obj.Addr) { + self.Emit("MOVQ", jit.Type(t), _AX) // MOVQ ${t}, AX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ", _VP, jit.Ptr(_SP, 8)) // MOVQ VP, 8(SP) + self.Emit("MOVQ", p, jit.Ptr(_SP, 16)) // MOVQ ${p}, 16(SP) + self.Emit("MOVQ", n, jit.Ptr(_SP, 24)) // MOVQ ${n}, 24(SP) + self.call_go(_F_mapassign_faststr) // CALL_GO ${fn} + self.Emit("MOVQ", jit.Ptr(_SP, 32), _VP) // MOVQ 32(SP), VP + self.mapaccess_ptr(t) +} + +func (self *_Assembler) mapassign_call(t reflect.Type, fn obj.Addr) { + self.Emit("MOVQ", jit.Type(t), _SI) // MOVQ ${t}, SI + self.Emit("MOVQ", _SI, jit.Ptr(_SP, 0)) // MOVQ SI, (SP) + self.Emit("MOVQ", _VP, jit.Ptr(_SP, 8)) // MOVQ VP, 8(SP) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16)) // MOVQ AX, 16(SP) + self.call_go(fn) // CALL_GO ${fn} + self.Emit("MOVQ", jit.Ptr(_SP, 24), _VP) // MOVQ 24(SP), VP +} + +func (self *_Assembler) mapassign_fastx(t reflect.Type, fn obj.Addr) { + self.mapassign_call(t, fn) + self.mapaccess_ptr(t) +} + +func (self *_Assembler) mapassign_utext(t reflect.Type, addressable bool) { + pv := false + vk := t.Key() + tk := t.Key() + + /* deref pointer if needed */ + if vk.Kind() == reflect.Ptr { + pv = true + vk = vk.Elem() + } + + /* addressable value with pointer receiver */ + if addressable { + pv = false + tk = reflect.PtrTo(tk) + } + + /* allocate the key, and call the unmarshaler */ + self.valloc(vk, _DI) // VALLOC ${vk}, DI + // must spill vk pointer since next call_go may invoke GC + self.Emit("MOVQ" , _DI, _VAR_vk) + self.Emit("MOVQ" , jit.Type(tk), _AX) // MOVQ ${tk}, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ" , _DI, jit.Ptr(_SP, 8)) // MOVQ DI, 8(SP) + self.Emit("MOVOU", _VAR_sv, _X0) // MOVOU sv, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 16)) // MOVOU X0, 16(SP) + self.call_go(_F_decodeTextUnmarshaler) // CALL_GO decodeTextUnmarshaler + self.Emit("MOVQ" , jit.Ptr(_SP, 32), _ET) // MOVQ 32(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _EP) // MOVQ 40(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error + self.Emit("MOVQ" , _VAR_vk, _AX) + + /* select the correct assignment function */ + if !pv { + self.mapassign_call(t, _F_mapassign) + } else { + self.mapassign_fastx(t, _F_mapassign_fast64ptr) + } +} + +/** External Unmarshaler Routines **/ + +var ( + _F_skip_one = jit.Imm(int64(native.S_skip_one)) + _F_skip_number = jit.Imm(int64(native.S_skip_number)) +) + +func (self *_Assembler) unmarshal_json(t reflect.Type, deref bool) { + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v + self.slice_from_r(_AX, 0) // SLICE_R AX, $0 + self.Emit("MOVQ" , _DI, _VAR_sv_p) // MOVQ DI, sv.p + self.Emit("MOVQ" , _SI, _VAR_sv_n) // MOVQ SI, sv.n + self.unmarshal_func(t, _F_decodeJsonUnmarshaler, deref) // UNMARSHAL json, ${t}, ${deref} +} + +func (self *_Assembler) unmarshal_text(t reflect.Type, deref bool) { + self.parse_string() // PARSE STRING + self.unquote_once(_VAR_sv_p, _VAR_sv_n, true, true) // UNQUOTE once, sv.p, sv.n + self.unmarshal_func(t, _F_decodeTextUnmarshaler, deref) // UNMARSHAL text, ${t}, ${deref} +} + +func (self *_Assembler) unmarshal_func(t reflect.Type, fn obj.Addr, deref bool) { + pt := t + vk := t.Kind() + + /* allocate the field if needed */ + if deref && vk == reflect.Ptr { + self.Emit("MOVQ" , _VP, _AX) // MOVQ VP, AX + self.Emit("MOVQ" , jit.Ptr(_AX, 0), _AX) // MOVQ (AX), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNZ" , "_deref_{n}") // JNZ _deref_{n} + self.valloc(t.Elem(), _AX) // VALLOC ${t.Elem()}, AX + self.WritePtrAX(3, jit.Ptr(_VP, 0), false) // MOVQ AX, (VP) + self.Link("_deref_{n}") // _deref_{n}: + } + + /* set value type */ + self.Emit("MOVQ", jit.Type(pt), _CX) // MOVQ ${pt}, CX + self.Emit("MOVQ", _CX, jit.Ptr(_SP, 0)) // MOVQ CX, (SP) + + /* set value pointer */ + if deref && vk == reflect.Ptr { + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) + } else { + self.Emit("MOVQ", _VP, jit.Ptr(_SP, 8)) // MOVQ VP, 8(SP) + } + + /* set the source string and call the unmarshaler */ + self.Emit("MOVOU", _VAR_sv, _X0) // MOVOU sv, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 16)) // MOVOU X0, 16(SP) + self.call_go(fn) // CALL_GO ${fn} + self.Emit("MOVQ" , jit.Ptr(_SP, 32), _ET) // MOVQ 32(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _EP) // MOVQ 40(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error +} + +/** Dynamic Decoding Routine **/ + +var ( + _F_decodeTypedPointer obj.Addr +) + +func init() { + _F_decodeTypedPointer = jit.Func(decodeTypedPointer) +} + +func (self *_Assembler) decode_dynamic(vt obj.Addr, vp obj.Addr) { + self.Emit("MOVQ" , _ARG_fv, _CX) // MOVQ fv, CX + self.Emit("MOVOU", _ARG_sp, _X0) // MOVOU sp, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 0)) // MOVOU X0, (SP) + self.Emit("MOVQ" , _IC, jit.Ptr(_SP, 16)) // MOVQ IC, 16(SP) + self.Emit("MOVQ" , vt, jit.Ptr(_SP, 24)) // MOVQ ${vt}, 24(SP) + self.Emit("MOVQ" , vp, jit.Ptr(_SP, 32)) // MOVQ ${vp}, 32(SP) + self.Emit("MOVQ" , _ST, jit.Ptr(_SP, 40)) // MOVQ ST, 40(SP) + self.Emit("MOVQ" , _CX, jit.Ptr(_SP, 48)) // MOVQ CX, 48(SP) + self.call_go(_F_decodeTypedPointer) // CALL_GO decodeTypedPointer + self.Emit("MOVQ" , jit.Ptr(_SP, 64), _ET) // MOVQ 64(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 72), _EP) // MOVQ 72(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error + self.Emit("MOVQ" , jit.Ptr(_SP, 56), _IC) // MOVQ 56(SP), IC +} + +/** OpCode Assembler Functions **/ + +var ( + _F_memequal = jit.Func(memequal) + _F_memmove = jit.Func(memmove) + _F_growslice = jit.Func(growslice) + _F_makeslice = jit.Func(makeslice) + _F_makemap_small = jit.Func(makemap_small) + _F_mapassign_fast64 = jit.Func(mapassign_fast64) +) + +var ( + _F_lspace = jit.Imm(int64(native.S_lspace)) + _F_strhash = jit.Imm(int64(caching.S_strhash)) +) + +var ( + _F_b64decode = jit.Imm(int64(_subr__b64decode)) + _F_decodeValue = jit.Imm(int64(_subr_decode_value)) +) + +var ( + _F_skip_array = jit.Imm(int64(native.S_skip_array)) + _F_skip_object = jit.Imm(int64(native.S_skip_object)) +) + +var ( + _F_FieldMap_GetCaseInsensitive obj.Addr +) + +const ( + _MODE_AVX2 = 1 << 2 +) + +const ( + _Fe_ID = int64(unsafe.Offsetof(caching.FieldEntry{}.ID)) + _Fe_Name = int64(unsafe.Offsetof(caching.FieldEntry{}.Name)) + _Fe_Hash = int64(unsafe.Offsetof(caching.FieldEntry{}.Hash)) +) + +const ( + _Vk_Ptr = int64(reflect.Ptr) + _Gt_KindFlags = int64(unsafe.Offsetof(rt.GoType{}.KindFlags)) +) + +func init() { + _F_FieldMap_GetCaseInsensitive = jit.Func((*caching.FieldMap).GetCaseInsensitive) +} + +func (self *_Assembler) _asm_OP_any(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_VP, 8), _CX) // MOVQ 8(VP), CX + self.Emit("TESTQ" , _CX, _CX) // TESTQ CX, CX + self.Sjmp("JZ" , "_decode_{n}") // JZ _decode_{n} + self.Emit("CMPQ" , _CX, _VP) // CMPQ CX, VP + self.Sjmp("JE" , "_decode_{n}") // JE _decode_{n} + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _AX) // MOVQ (VP), AX + self.Emit("MOVBLZX", jit.Ptr(_AX, _Gt_KindFlags), _DX) // MOVBLZX _Gt_KindFlags(AX), DX + self.Emit("ANDL" , jit.Imm(rt.F_kind_mask), _DX) // ANDL ${F_kind_mask}, DX + self.Emit("CMPL" , _DX, jit.Imm(_Vk_Ptr)) // CMPL DX, ${reflect.Ptr} + self.Sjmp("JNE" , "_decode_{n}") // JNE _decode_{n} + self.Emit("LEAQ" , jit.Ptr(_VP, 8), _DI) // LEAQ 8(VP), DI + self.decode_dynamic(_AX, _DI) // DECODE AX, DI + self.Sjmp("JMP" , "_decode_end_{n}") // JMP _decode_end_{n} + self.Link("_decode_{n}") // _decode_{n}: + self.Emit("MOVQ" , _ARG_fv, _DF) // MOVQ fv, DF + self.Emit("MOVQ" , _ST, jit.Ptr(_SP, 0)) // MOVQ _ST, (SP) + self.call(_F_decodeValue) // CALL decodeValue + self.Emit("TESTQ" , _EP, _EP) // TESTQ EP, EP + self.Sjmp("JNZ" , _LB_parsing_error) // JNZ _parsing_error + self.Link("_decode_end_{n}") // _decode_end_{n}: +} + +func (self *_Assembler) _asm_OP_dyn(p *_Instr) { + self.Emit("MOVQ" , jit.Type(p.vt()), _ET) // MOVQ ${p.vt()}, ET + self.Emit("CMPQ" , jit.Ptr(_VP, 8), jit.Imm(0)) // CMPQ 8(VP), $0 + self.Sjmp("JE" , _LB_type_error) // JE _type_error + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _AX) // MOVQ (VP), AX + self.Emit("MOVQ" , jit.Ptr(_AX, 8), _AX) // MOVQ 8(AX), AX + self.Emit("MOVBLZX", jit.Ptr(_AX, _Gt_KindFlags), _DX) // MOVBLZX _Gt_KindFlags(AX), DX + self.Emit("ANDL" , jit.Imm(rt.F_kind_mask), _DX) // ANDL ${F_kind_mask}, DX + self.Emit("CMPL" , _DX, jit.Imm(_Vk_Ptr)) // CMPL DX, ${reflect.Ptr} + self.Sjmp("JNE" , _LB_type_error) // JNE _type_error + self.Emit("LEAQ" , jit.Ptr(_VP, 8), _DI) // LEAQ 8(VP), DI + self.decode_dynamic(_AX, _DI) // DECODE AX, DI + self.Link("_decode_end_{n}") // _decode_end_{n}: +} + +func (self *_Assembler) _asm_OP_str(_ *_Instr) { + self.parse_string() // PARSE STRING + self.unquote_once(jit.Ptr(_VP, 0), jit.Ptr(_VP, 8), false, true) // UNQUOTE once, (VP), 8(VP) +} + +func (self *_Assembler) _asm_OP_bin(_ *_Instr) { + self.parse_string() // PARSE STRING + self.slice_from(_VAR_st_Iv, -1) // SLICE st.Iv, $-1 + self.Emit("MOVQ" , _DI, jit.Ptr(_VP, 0)) // MOVQ DI, (VP) + self.Emit("MOVQ" , _SI, jit.Ptr(_VP, 8)) // MOVQ SI, 8(VP) + self.Emit("SHRQ" , jit.Imm(2), _SI) // SHRQ $2, SI + self.Emit("LEAQ" , jit.Sib(_SI, _SI, 2, 0), _SI) // LEAQ (SI)(SI*2), SI + self.Emit("MOVQ" , _SI, jit.Ptr(_VP, 16)) // MOVQ SI, 16(VP) + self.malloc(_SI, _SI) // MALLOC SI, SI + + // TODO: due to base64x's bug, only use AVX mode now + self.Emit("MOVL", jit.Imm(_MODE_JSON), _CX) // MOVL $_MODE_JSON, CX + + /* call the decoder */ + self.Emit("XORL" , _DX, _DX) // XORL DX, DX + self.Emit("MOVQ" , _VP, _DI) // MOVQ VP, DI + + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _R9) // MOVQ SI, (VP) + self.WriteRecNotAX(4, _SI, jit.Ptr(_VP, 0), true, false) // XCHGQ SI, (VP) + self.Emit("MOVQ" , _R9, _SI) + + self.Emit("XCHGQ", _DX, jit.Ptr(_VP, 8)) // XCHGQ DX, 8(VP) + self.call(_F_b64decode) // CALL b64decode + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_base64_error) // JS _base64_error + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) +} + +func (self *_Assembler) _asm_OP_bool(_ *_Instr) { + self.Emit("LEAQ", jit.Ptr(_IC, 4), _AX) // LEAQ 4(IC), AX + self.Emit("CMPQ", _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , _LB_eof_error) // JA _eof_error + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm('f')) // CMPB (IP)(IC), $'f' + self.Sjmp("JE" , "_false_{n}") // JE _false_{n} + self.Emit("MOVL", jit.Imm(_IM_true), _CX) // MOVL $"true", CX + self.Emit("CMPL", _CX, jit.Sib(_IP, _IC, 1, 0)) // CMPL CX, (IP)(IC) + self.Sjmp("JE" , "_bool_true_{n}") + + // try to skip the value + self.Emit("MOVQ", _IC, _VAR_ic) + self.Emit("MOVQ", _T_bool, _ET) + self.Emit("MOVQ", _ET, _VAR_et) + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_end_{n}", 4) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_one) + + self.Link("_bool_true_{n}") + self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC + self.Emit("MOVB", jit.Imm(1), jit.Ptr(_VP, 0)) // MOVB $1, (VP) + self.Sjmp("JMP" , "_end_{n}") // JMP _end_{n} + self.Link("_false_{n}") // _false_{n}: + self.Emit("ADDQ", jit.Imm(1), _AX) // ADDQ $1, AX + self.Emit("ADDQ", jit.Imm(1), _IC) // ADDQ $1, IC + self.Emit("CMPQ", _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , _LB_eof_error) // JA _eof_error + self.Emit("MOVL", jit.Imm(_IM_alse), _CX) // MOVL $"alse", CX + self.Emit("CMPL", _CX, jit.Sib(_IP, _IC, 1, 0)) // CMPL CX, (IP)(IC) + self.Sjmp("JNE" , _LB_im_error) // JNE _im_error + self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("MOVB", _AX, jit.Ptr(_VP, 0)) // MOVB AX, (VP) + self.Link("_end_{n}") // _end_{n}: +} + +func (self *_Assembler) _asm_OP_num(_ *_Instr) { + self.Emit("MOVQ", jit.Imm(0), _VAR_fl) + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm('"')) + self.Emit("MOVQ", _IC, _BP) + self.Sjmp("JNE", "_skip_number_{n}") + self.Emit("MOVQ", jit.Imm(1), _VAR_fl) + self.Emit("ADDQ", jit.Imm(1), _IC) + self.Link("_skip_number_{n}") + + /* call skip_number */ + self.call_sf(_F_skip_number) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNS" , "_num_next_{n}") + + /* call skip one */ + self.Emit("MOVQ", _BP, _VAR_ic) + self.Emit("MOVQ", _T_number, _ET) + self.Emit("MOVQ", _ET, _VAR_et) + self.Byte(0x4c, 0x8d, 0x0d) + self.Sref("_num_end_{n}", 4) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_one) + + /* assgin string */ + self.Link("_num_next_{n}") + self.slice_from_r(_AX, 0) + self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv) + self.Sjmp("JNC", "_num_write_{n}") + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_num_write_{n}", 4) + self.Sjmp("JMP", "_copy_string") + self.Link("_num_write_{n}") + self.Emit("MOVQ", _SI, jit.Ptr(_VP, 8)) // MOVQ SI, 8(VP) + self.WriteRecNotAX(13, _DI, jit.Ptr(_VP, 0), false, false) + + /* check if quoted */ + self.Emit("CMPQ", _VAR_fl, jit.Imm(1)) + self.Sjmp("JNE", "_num_end_{n}") + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm('"')) + self.Sjmp("JNE", _LB_char_0_error) + self.Emit("ADDQ", jit.Imm(1), _IC) + self.Link("_num_end_{n}") +} + +func (self *_Assembler) _asm_OP_i8(ins *_Instr) { + var pin = "_i8_end_{n}" + self.parse_signed(int8Type, pin, -1) // PARSE int8 + self.range_signed(_I_int8, _T_int8, math.MinInt8, math.MaxInt8) // RANGE int8 + self.Emit("MOVB", _AX, jit.Ptr(_VP, 0)) // MOVB AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_i16(ins *_Instr) { + var pin = "_i16_end_{n}" + self.parse_signed(int16Type, pin, -1) // PARSE int16 + self.range_signed(_I_int16, _T_int16, math.MinInt16, math.MaxInt16) // RANGE int16 + self.Emit("MOVW", _AX, jit.Ptr(_VP, 0)) // MOVW AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_i32(ins *_Instr) { + var pin = "_i32_end_{n}" + self.parse_signed(int32Type, pin, -1) // PARSE int32 + self.range_signed(_I_int32, _T_int32, math.MinInt32, math.MaxInt32) // RANGE int32 + self.Emit("MOVL", _AX, jit.Ptr(_VP, 0)) // MOVL AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_i64(ins *_Instr) { + var pin = "_i64_end_{n}" + self.parse_signed(int64Type, pin, -1) // PARSE int64 + self.Emit("MOVQ", _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.Emit("MOVQ", _AX, jit.Ptr(_VP, 0)) // MOVQ AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_u8(ins *_Instr) { + var pin = "_u8_end_{n}" + self.parse_unsigned(uint8Type, pin, -1) // PARSE uint8 + self.range_unsigned(_I_uint8, _T_uint8, math.MaxUint8) // RANGE uint8 + self.Emit("MOVB", _AX, jit.Ptr(_VP, 0)) // MOVB AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_u16(ins *_Instr) { + var pin = "_u16_end_{n}" + self.parse_unsigned(uint16Type, pin, -1) // PARSE uint16 + self.range_unsigned(_I_uint16, _T_uint16, math.MaxUint16) // RANGE uint16 + self.Emit("MOVW", _AX, jit.Ptr(_VP, 0)) // MOVW AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_u32(ins *_Instr) { + var pin = "_u32_end_{n}" + self.parse_unsigned(uint32Type, pin, -1) // PARSE uint32 + self.range_unsigned(_I_uint32, _T_uint32, math.MaxUint32) // RANGE uint32 + self.Emit("MOVL", _AX, jit.Ptr(_VP, 0)) // MOVL AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_u64(ins *_Instr) { + var pin = "_u64_end_{n}" + self.parse_unsigned(uint64Type, pin, -1) // PARSE uint64 + self.Emit("MOVQ", _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.Emit("MOVQ", _AX, jit.Ptr(_VP, 0)) // MOVQ AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_f32(ins *_Instr) { + var pin = "_f32_end_{n}" + self.parse_number(float32Type, pin, -1) // PARSE NUMBER + self.range_single() // RANGE float32 + self.Emit("MOVSS", _X0, jit.Ptr(_VP, 0)) // MOVSS X0, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_f64(ins *_Instr) { + var pin = "_f64_end_{n}" + self.parse_number(float64Type, pin, -1) // PARSE NUMBER + self.Emit("MOVSD", _VAR_st_Dv, _X0) // MOVSD st.Dv, X0 + self.Emit("MOVSD", _X0, jit.Ptr(_VP, 0)) // MOVSD X0, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_unquote(ins *_Instr) { + self.check_eof(2) + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm('\\')) // CMPB (IP)(IC), $'\\' + self.Sjmp("JNE" , _LB_char_0_error) // JNE _char_0_error + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 1), jit.Imm('"')) // CMPB 1(IP)(IC), $'"' + self.Sjmp("JNE" , _LB_char_1_error) // JNE _char_1_error + self.Emit("ADDQ", jit.Imm(2), _IC) // ADDQ $2, IC + self.parse_string() // PARSE STRING + self.unquote_twice(jit.Ptr(_VP, 0), jit.Ptr(_VP, 8), false) // UNQUOTE twice, (VP), 8(VP) +} + +func (self *_Assembler) _asm_OP_nil_1(_ *_Instr) { + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("MOVQ", _AX, jit.Ptr(_VP, 0)) // MOVQ AX, (VP) +} + +func (self *_Assembler) _asm_OP_nil_2(_ *_Instr) { + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_VP, 0)) // MOVOU X0, (VP) +} + +func (self *_Assembler) _asm_OP_nil_3(_ *_Instr) { + self.Emit("XORL" , _AX, _AX) // XORL AX, AX + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_VP, 0)) // MOVOU X0, (VP) + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 16)) // MOVOU X0, 16(VP) +} + +func (self *_Assembler) _asm_OP_deref(p *_Instr) { + self.vfollow(p.vt()) +} + +func (self *_Assembler) _asm_OP_index(p *_Instr) { + self.Emit("MOVQ", jit.Imm(p.i64()), _AX) // MOVQ ${p.vi()}, AX + self.Emit("ADDQ", _AX, _VP) // ADDQ _AX, _VP +} + +func (self *_Assembler) _asm_OP_is_null(p *_Instr) { + self.Emit("LEAQ" , jit.Ptr(_IC, 4), _AX) // LEAQ 4(IC), AX + self.Emit("CMPQ" , _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , "_not_null_{n}") // JA _not_null_{n} + self.Emit("CMPL" , jit.Sib(_IP, _IC, 1, 0), jit.Imm(_IM_null)) // CMPL (IP)(IC), $"null" + self.Emit("CMOVQEQ", _AX, _IC) // CMOVQEQ AX, IC + self.Xjmp("JE" , p.vi()) // JE {p.vi()} + self.Link("_not_null_{n}") // _not_null_{n}: +} + +func (self *_Assembler) _asm_OP_is_null_quote(p *_Instr) { + self.Emit("LEAQ" , jit.Ptr(_IC, 5), _AX) // LEAQ 4(IC), AX + self.Emit("CMPQ" , _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , "_not_null_quote_{n}") // JA _not_null_quote_{n} + self.Emit("CMPL" , jit.Sib(_IP, _IC, 1, 0), jit.Imm(_IM_null)) // CMPL (IP)(IC), $"null" + self.Sjmp("JNE" , "_not_null_quote_{n}") // JNE _not_null_quote_{n} + self.Emit("CMPB" , jit.Sib(_IP, _IC, 1, 4), jit.Imm('"')) // CMPB 4(IP)(IC), $'"' + self.Emit("CMOVQEQ", _AX, _IC) // CMOVQEQ AX, IC + self.Xjmp("JE" , p.vi()) // JE {p.vi()} + self.Link("_not_null_quote_{n}") // _not_null_quote_{n}: +} + +func (self *_Assembler) _asm_OP_map_init(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _AX) // MOVQ (VP), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNZ" , "_end_{n}") // JNZ _end_{n} + self.call_go(_F_makemap_small) // CALL_GO makemap_small + self.Emit("MOVQ" , jit.Ptr(_SP, 0), _AX) // MOVQ (SP), AX + self.WritePtrAX(6, jit.Ptr(_VP, 0), false) // MOVQ AX, (VP) + self.Link("_end_{n}") // _end_{n}: + self.Emit("MOVQ" , _AX, _VP) // MOVQ AX, VP +} + +func (self *_Assembler) _asm_OP_map_key_i8(p *_Instr) { + self.parse_signed(int8Type, "", p.vi()) // PARSE int8 + self.range_signed(_I_int8, _T_int8, math.MinInt8, math.MaxInt8) // RANGE int8 + self.mapassign_std(p.vt(), _VAR_st_Iv) // MAPASSIGN int8, mapassign, st.Iv +} + +func (self *_Assembler) _asm_OP_map_key_i16(p *_Instr) { + self.parse_signed(int16Type, "", p.vi()) // PARSE int16 + self.range_signed(_I_int16, _T_int16, math.MinInt16, math.MaxInt16) // RANGE int16 + self.mapassign_std(p.vt(), _VAR_st_Iv) // MAPASSIGN int16, mapassign, st.Iv +} + +func (self *_Assembler) _asm_OP_map_key_i32(p *_Instr) { + self.parse_signed(int32Type, "", p.vi()) // PARSE int32 + self.range_signed(_I_int32, _T_int32, math.MinInt32, math.MaxInt32) // RANGE int32 + if vt := p.vt(); !mapfast(vt) { + self.mapassign_std(vt, _VAR_st_Iv) // MAPASSIGN int32, mapassign, st.Iv + } else { + self.mapassign_fastx(vt, _F_mapassign_fast32) // MAPASSIGN int32, mapassign_fast32 + } +} + +func (self *_Assembler) _asm_OP_map_key_i64(p *_Instr) { + self.parse_signed(int64Type, "", p.vi()) // PARSE int64 + if vt := p.vt(); !mapfast(vt) { + self.mapassign_std(vt, _VAR_st_Iv) // MAPASSIGN int64, mapassign, st.Iv + } else { + self.Emit("MOVQ", _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.mapassign_fastx(vt, _F_mapassign_fast64) // MAPASSIGN int64, mapassign_fast64 + } +} + +func (self *_Assembler) _asm_OP_map_key_u8(p *_Instr) { + self.parse_unsigned(uint8Type, "", p.vi()) // PARSE uint8 + self.range_unsigned(_I_uint8, _T_uint8, math.MaxUint8) // RANGE uint8 + self.mapassign_std(p.vt(), _VAR_st_Iv) // MAPASSIGN uint8, vt.Iv +} + +func (self *_Assembler) _asm_OP_map_key_u16(p *_Instr) { + self.parse_unsigned(uint16Type, "", p.vi()) // PARSE uint16 + self.range_unsigned(_I_uint16, _T_uint16, math.MaxUint16) // RANGE uint16 + self.mapassign_std(p.vt(), _VAR_st_Iv) // MAPASSIGN uint16, vt.Iv +} + +func (self *_Assembler) _asm_OP_map_key_u32(p *_Instr) { + self.parse_unsigned(uint32Type, "", p.vi()) // PARSE uint32 + self.range_unsigned(_I_uint32, _T_uint32, math.MaxUint32) // RANGE uint32 + if vt := p.vt(); !mapfast(vt) { + self.mapassign_std(vt, _VAR_st_Iv) // MAPASSIGN uint32, vt.Iv + } else { + self.mapassign_fastx(vt, _F_mapassign_fast32) // MAPASSIGN uint32, mapassign_fast32 + } +} + +func (self *_Assembler) _asm_OP_map_key_u64(p *_Instr) { + self.parse_unsigned(uint64Type, "", p.vi()) // PARSE uint64 + if vt := p.vt(); !mapfast(vt) { + self.mapassign_std(vt, _VAR_st_Iv) // MAPASSIGN uint64, vt.Iv + } else { + self.Emit("MOVQ", _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.mapassign_fastx(vt, _F_mapassign_fast64) // MAPASSIGN uint64, mapassign_fast64 + } +} + +func (self *_Assembler) _asm_OP_map_key_f32(p *_Instr) { + self.parse_number(float32Type, "", p.vi()) // PARSE NUMBER + self.range_single() // RANGE float32 + self.Emit("MOVSS", _X0, _VAR_st_Dv) // MOVSS X0, st.Dv + self.mapassign_std(p.vt(), _VAR_st_Dv) // MAPASSIGN ${p.vt()}, mapassign, st.Dv +} + +func (self *_Assembler) _asm_OP_map_key_f64(p *_Instr) { + self.parse_number(float64Type, "", p.vi()) // PARSE NUMBER + self.mapassign_std(p.vt(), _VAR_st_Dv) // MAPASSIGN ${p.vt()}, mapassign, st.Dv +} + +func (self *_Assembler) _asm_OP_map_key_str(p *_Instr) { + self.parse_string() // PARSE STRING + self.unquote_once(_VAR_sv_p, _VAR_sv_n, true, true) // UNQUOTE once, sv.p, sv.n + if vt := p.vt(); !mapfast(vt) { + self.valloc(vt.Key(), _DI) + self.Emit("MOVOU", _VAR_sv, _X0) + self.Emit("MOVOU", _X0, jit.Ptr(_DI, 0)) + self.mapassign_std(vt, jit.Ptr(_DI, 0)) + } else { + self.Emit("MOVQ", _VAR_sv_p, _DI) // MOVQ sv.p, DI + self.Emit("MOVQ", _VAR_sv_n, _SI) // MOVQ sv.n, SI + self.mapassign_str_fast(vt, _DI, _SI) // MAPASSIGN string, DI, SI + } +} + +func (self *_Assembler) _asm_OP_map_key_utext(p *_Instr) { + self.parse_string() // PARSE STRING + self.unquote_once(_VAR_sv_p, _VAR_sv_n, true, true) // UNQUOTE once, sv.p, sv.n + self.mapassign_utext(p.vt(), false) // MAPASSIGN utext, ${p.vt()}, false +} + +func (self *_Assembler) _asm_OP_map_key_utext_p(p *_Instr) { + self.parse_string() // PARSE STRING + self.unquote_once(_VAR_sv_p, _VAR_sv_n, true, false) // UNQUOTE once, sv.p, sv.n + self.mapassign_utext(p.vt(), true) // MAPASSIGN utext, ${p.vt()}, true +} + +func (self *_Assembler) _asm_OP_array_skip(_ *_Instr) { + self.call_sf(_F_skip_array) // CALL_SF skip_array + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v +} + +func (self *_Assembler) _asm_OP_array_clear(p *_Instr) { + self.mem_clear_rem(p.i64(), true) +} + +func (self *_Assembler) _asm_OP_array_clear_p(p *_Instr) { + self.mem_clear_rem(p.i64(), false) +} + +func (self *_Assembler) _asm_OP_slice_init(p *_Instr) { + self.Emit("XORL" , _AX, _AX) // XORL AX, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) + self.Emit("MOVQ" , jit.Ptr(_VP, 16), _AX) // MOVQ 16(VP), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNZ" , "_done_{n}") // JNZ _done_{n} + self.Emit("MOVQ" , jit.Imm(_MinSlice), _CX) // MOVQ ${_MinSlice}, CX + self.Emit("MOVQ" , _CX, jit.Ptr(_VP, 16)) // MOVQ CX, 16(VP) + self.Emit("MOVQ" , jit.Type(p.vt()), _DX) // MOVQ ${p.vt()}, DX + self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 0)) // MOVQ DX, (SP) + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) + self.Emit("MOVQ" , _CX, jit.Ptr(_SP, 16)) // MOVQ CX, 16(SP) + self.call_go(_F_makeslice) // CALL_GO makeslice + self.Emit("MOVQ" , jit.Ptr(_SP, 24), _AX) // MOVQ 24(SP), AX + self.WritePtrAX(7, jit.Ptr(_VP, 0), false) // MOVQ AX, (VP) + self.Link("_done_{n}") // _done_{n}: + self.Emit("XORL" , _AX, _AX) // XORL AX, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) +} + +func (self *_Assembler) _asm_OP_slice_append(p *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_VP, 8), _AX) // MOVQ 8(VP), AX + self.Emit("CMPQ" , _AX, jit.Ptr(_VP, 16)) // CMPQ AX, 16(VP) + self.Sjmp("JB" , "_index_{n}") // JB _index_{n} + self.Emit("MOVQ" , jit.Type(p.vt()), _AX) // MOVQ ${p.vt()}, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVOU", jit.Ptr(_VP, 0), _X0) // MOVOU (VP), X0 + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 8)) // MOVOU X0, 8(SP) + self.Emit("MOVQ" , jit.Ptr(_VP, 16), _AX) // MOVQ 16(VP), AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 24)) // MOVQ AX, 24(SP) + self.Emit("SHLQ" , jit.Imm(1), _AX) // SHLQ $1, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 32)) // MOVQ AX, 32(SP) + self.call_go(_F_growslice) // CALL_GO growslice + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _DI) // MOVQ 40(SP), DI + self.Emit("MOVQ" , jit.Ptr(_SP, 48), _AX) // MOVQ 48(SP), AX + self.Emit("MOVQ" , jit.Ptr(_SP, 56), _SI) // MOVQ 56(SP), SI + self.WriteRecNotAX(8, _DI, jit.Ptr(_VP, 0), true, true)// MOVQ DI, (VP) + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) + self.Emit("MOVQ" , _SI, jit.Ptr(_VP, 16)) // MOVQ SI, 16(VP) + self.Link("_index_{n}") // _index_{n}: + self.Emit("ADDQ" , jit.Imm(1), jit.Ptr(_VP, 8)) // ADDQ $1, 8(VP) + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _VP) // MOVQ (VP), VP + self.Emit("MOVQ" , jit.Imm(int64(p.vlen())), _CX) // MOVQ ${p.vlen()}, CX + self.From("MULQ" , _CX) // MULQ CX + self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP +} + +func (self *_Assembler) _asm_OP_object_skip(_ *_Instr) { + self.call_sf(_F_skip_object) // CALL_SF skip_object + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v +} + +func (self *_Assembler) _asm_OP_object_next(_ *_Instr) { + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v +} + +func (self *_Assembler) _asm_OP_struct_field(p *_Instr) { + assert_eq(caching.FieldEntrySize, 32, "invalid field entry size") + self.Emit("MOVQ" , jit.Imm(-1), _AX) // MOVQ $-1, AX + self.Emit("MOVQ" , _AX, _VAR_sr) // MOVQ AX, sr + self.parse_string() // PARSE STRING + self.unquote_once(_VAR_sv_p, _VAR_sv_n, true, false) // UNQUOTE once, sv.p, sv.n + self.Emit("LEAQ" , _VAR_sv, _AX) // LEAQ sv, AX + self.Emit("XORL" , _CX, _CX) // XORL CX, CX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ" , _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP) + self.call_go(_F_strhash) // CALL_GO strhash + self.Emit("MOVQ" , jit.Ptr(_SP, 16), _AX) // MOVQ 16(SP), AX + self.Emit("MOVQ" , _AX, _R9) // MOVQ AX, R9 + self.Emit("MOVQ" , jit.Imm(freezeFields(p.vf())), _CX) // MOVQ ${p.vf()}, CX + self.Emit("MOVQ" , jit.Ptr(_CX, caching.FieldMap_b), _SI) // MOVQ FieldMap.b(CX), SI + self.Emit("MOVQ" , jit.Ptr(_CX, caching.FieldMap_N), _CX) // MOVQ FieldMap.N(CX), CX + self.Emit("TESTQ", _CX, _CX) // TESTQ CX, CX + self.Sjmp("JZ" , "_try_lowercase_{n}") // JZ _try_lowercase_{n} + self.Link("_loop_{n}") // _loop_{n}: + self.Emit("XORL" , _DX, _DX) // XORL DX, DX + self.From("DIVQ" , _CX) // DIVQ CX + self.Emit("LEAQ" , jit.Ptr(_DX, 1), _AX) // LEAQ 1(DX), AX + self.Emit("SHLQ" , jit.Imm(5), _DX) // SHLQ $5, DX + self.Emit("LEAQ" , jit.Sib(_SI, _DX, 1, 0), _DI) // LEAQ (SI)(DX), DI + self.Emit("MOVQ" , jit.Ptr(_DI, _Fe_Hash), _R8) // MOVQ FieldEntry.Hash(DI), R8 + self.Emit("TESTQ", _R8, _R8) // TESTQ R8, R8 + self.Sjmp("JZ" , "_try_lowercase_{n}") // JZ _try_lowercase_{n} + self.Emit("CMPQ" , _R8, _R9) // CMPQ R8, R9 + self.Sjmp("JNE" , "_loop_{n}") // JNE _loop_{n} + self.Emit("MOVQ" , jit.Ptr(_DI, _Fe_Name + 8), _DX) // MOVQ FieldEntry.Name+8(DI), DX + self.Emit("CMPQ" , _DX, _VAR_sv_n) // CMPQ DX, sv.n + self.Sjmp("JNE" , "_loop_{n}") // JNE _loop_{n} + self.Emit("MOVQ" , jit.Ptr(_DI, _Fe_ID), _R8) // MOVQ FieldEntry.ID(DI), R8 + self.Emit("MOVQ" , _AX, _VAR_ss_AX) // MOVQ AX, ss.AX + self.Emit("MOVQ" , _CX, _VAR_ss_CX) // MOVQ CX, ss.CX + self.Emit("MOVQ" , _SI, _VAR_ss_SI) // MOVQ SI, ss.SI + self.Emit("MOVQ" , _R8, _VAR_ss_R8) // MOVQ R8, ss.R8 + self.Emit("MOVQ" , _R9, _VAR_ss_R9) // MOVQ R9, ss.R9 + self.Emit("MOVQ" , _VAR_sv_p, _AX) // MOVQ _VAR_sv_p, AX + self.Emit("MOVQ" , jit.Ptr(_DI, _Fe_Name), _CX) // MOVQ FieldEntry.Name(DI), CX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ" , _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP) + self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 16)) // MOVQ DX, 16(SP) + self.call_go(_F_memequal) // CALL_GO memequal + self.Emit("MOVQ" , _VAR_ss_AX, _AX) // MOVQ ss.AX, AX + self.Emit("MOVQ" , _VAR_ss_CX, _CX) // MOVQ ss.CX, CX + self.Emit("MOVQ" , _VAR_ss_SI, _SI) // MOVQ ss.SI, SI + self.Emit("MOVQ" , _VAR_ss_R9, _R9) // MOVQ ss.R9, R9 + self.Emit("MOVB" , jit.Ptr(_SP, 24), _DX) // MOVB 24(SP), DX + self.Emit("TESTB", _DX, _DX) // TESTB DX, DX + self.Sjmp("JZ" , "_loop_{n}") // JZ _loop_{n} + self.Emit("MOVQ" , _VAR_ss_R8, _R8) // MOVQ ss.R8, R8 + self.Emit("MOVQ" , _R8, _VAR_sr) // MOVQ R8, sr + self.Sjmp("JMP" , "_end_{n}") // JMP _end_{n} + self.Link("_try_lowercase_{n}") // _try_lowercase_{n}: + self.Emit("MOVQ" , jit.Imm(referenceFields(p.vf())), _AX) // MOVQ ${p.vf()}, AX + self.Emit("MOVOU", _VAR_sv, _X0) // MOVOU sv, X0 + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 8)) // MOVOU X0, 8(SP) + self.call_go(_F_FieldMap_GetCaseInsensitive) // CALL_GO FieldMap::GetCaseInsensitive + self.Emit("MOVQ" , jit.Ptr(_SP, 24), _AX) // MOVQ 24(SP), AX + self.Emit("MOVQ" , _AX, _VAR_sr) // MOVQ AX, _VAR_sr + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNS" , "_end_{n}") // JNS _end_{n} + self.Emit("BTQ" , jit.Imm(_F_disable_unknown), _ARG_fv) // BTQ ${_F_disable_unknown}, fv + self.Sjmp("JC" , _LB_field_error) // JC _field_error + self.Link("_end_{n}") // _end_{n}: +} + +func (self *_Assembler) _asm_OP_unmarshal(p *_Instr) { + self.unmarshal_json(p.vt(), true) +} + +func (self *_Assembler) _asm_OP_unmarshal_p(p *_Instr) { + self.unmarshal_json(p.vt(), false) +} + +func (self *_Assembler) _asm_OP_unmarshal_text(p *_Instr) { + self.unmarshal_text(p.vt(), true) +} + +func (self *_Assembler) _asm_OP_unmarshal_text_p(p *_Instr) { + self.unmarshal_text(p.vt(), false) +} + +func (self *_Assembler) _asm_OP_lspace(_ *_Instr) { + self.lspace("_{n}") +} + +func (self *_Assembler) lspace(subfix string) { + var label = "_lspace" + subfix + + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , _LB_eof_error) // JAE _eof_error + self.Emit("MOVQ" , jit.Imm(_BM_space), _DX) // MOVQ _BM_space, DX + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' ' + self.Sjmp("JA" , label) // JA _nospace_{n} + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , label) // JNC _nospace_{n} + + /* test up to 4 characters */ + for i := 0; i < 3; i++ { + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , _LB_eof_error) // JAE _eof_error + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' ' + self.Sjmp("JA" , label) // JA _nospace_{n} + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , label) // JNC _nospace_{n} + } + + /* handle over to the native function */ + self.Emit("MOVQ" , _IP, _DI) // MOVQ IP, DI + self.Emit("MOVQ" , _IL, _SI) // MOVQ IL, SI + self.Emit("MOVQ" , _IC, _DX) // MOVQ IC, DX + self.call(_F_lspace) // CALL lspace + self.Emit("TESTQ" , _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parsing_error_v + self.Emit("CMPQ" , _AX, _IL) // CMPQ AX, IL + self.Sjmp("JAE" , _LB_eof_error) // JAE _eof_error + self.Emit("MOVQ" , _AX, _IC) // MOVQ AX, IC + self.Link(label) // _nospace_{n}: +} + +func (self *_Assembler) _asm_OP_match_char(p *_Instr) { + self.check_eof(1) + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(p.vb()))) // CMPB (IP)(IC), ${p.vb()} + self.Sjmp("JNE" , _LB_char_0_error) // JNE _char_0_error + self.Emit("ADDQ", jit.Imm(1), _IC) // ADDQ $1, IC +} + +func (self *_Assembler) _asm_OP_check_char(p *_Instr) { + self.check_eof(1) + self.Emit("LEAQ" , jit.Ptr(_IC, 1), _AX) // LEAQ 1(IC), AX + self.Emit("CMPB" , jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(p.vb()))) // CMPB (IP)(IC), ${p.vb()} + self.Emit("CMOVQEQ", _AX, _IC) // CMOVQEQ AX, IC + self.Xjmp("JE" , p.vi()) // JE {p.vi()} +} + +func (self *_Assembler) _asm_OP_check_char_0(p *_Instr) { + self.check_eof(1) + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(p.vb()))) // CMPB (IP)(IC), ${p.vb()} + self.Xjmp("JE" , p.vi()) // JE {p.vi()} +} + +func (self *_Assembler) _asm_OP_add(p *_Instr) { + self.Emit("ADDQ", jit.Imm(int64(p.vi())), _IC) // ADDQ ${p.vi()}, IC +} + +func (self *_Assembler) _asm_OP_load(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, 0), _VP) // MOVQ (ST)(AX), VP +} + +func (self *_Assembler) _asm_OP_save(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _CX) // MOVQ (ST), CX + self.Emit("CMPQ", _CX, jit.Imm(_MaxStackBytes)) // CMPQ CX, ${_MaxStackBytes} + self.Sjmp("JAE" , _LB_stack_error) // JA _stack_error + self.WriteRecNotAX(0 , _VP, jit.Sib(_ST, _CX, 1, 8), false, false) // MOVQ VP, 8(ST)(CX) + self.Emit("ADDQ", jit.Imm(8), _CX) // ADDQ $8, CX + self.Emit("MOVQ", _CX, jit.Ptr(_ST, 0)) // MOVQ CX, (ST) +} + +func (self *_Assembler) _asm_OP_drop(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("SUBQ", jit.Imm(8), _AX) // SUBQ $8, AX + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, 8), _VP) // MOVQ 8(ST)(AX), VP + self.Emit("MOVQ", _AX, jit.Ptr(_ST, 0)) // MOVQ AX, (ST) + self.Emit("XORL", _ET, _ET) // XORL ET, ET + self.Emit("MOVQ", _ET, jit.Sib(_ST, _AX, 1, 8)) // MOVQ ET, 8(ST)(AX) +} + +func (self *_Assembler) _asm_OP_drop_2(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("SUBQ" , jit.Imm(16), _AX) // SUBQ $16, AX + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 8), _VP) // MOVQ 8(ST)(AX), VP + self.Emit("MOVQ" , _AX, jit.Ptr(_ST, 0)) // MOVQ AX, (ST) + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 8)) // MOVOU X0, 8(ST)(AX) +} + +func (self *_Assembler) _asm_OP_recurse(p *_Instr) { + self.Emit("MOVQ", jit.Type(p.vt()), _AX) // MOVQ ${p.vt()}, AX + self.decode_dynamic(_AX, _VP) // DECODE AX, VP +} + +func (self *_Assembler) _asm_OP_goto(p *_Instr) { + self.Xjmp("JMP", p.vi()) +} + +func (self *_Assembler) _asm_OP_switch(p *_Instr) { + self.Emit("MOVQ", _VAR_sr, _AX) // MOVQ sr, AX + self.Emit("CMPQ", _AX, jit.Imm(p.i64())) // CMPQ AX, ${len(p.vs())} + self.Sjmp("JAE" , "_default_{n}") // JAE _default_{n} + + /* jump table selector */ + self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI + self.Sref("_switch_table_{n}", 4) // .... &_switch_table_{n} + self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, 0), _AX) // MOVLQSX (DI)(AX*4), AX + self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX + self.Rjmp("JMP" , _AX) // JMP AX + self.Link("_switch_table_{n}") // _switch_table_{n}: + + /* generate the jump table */ + for i, v := range p.vs() { + self.Xref(v, int64(-i) * 4) + } + + /* default case */ + self.Link("_default_{n}") + self.NOP() +} + +func (self *_Assembler) print_gc(i int, p1 *_Instr, p2 *_Instr) { + self.Emit("MOVQ", jit.Imm(int64(p2.op())), jit.Ptr(_SP, 16))// MOVQ $(p2.op()), 16(SP) + self.Emit("MOVQ", jit.Imm(int64(p1.op())), jit.Ptr(_SP, 8)) // MOVQ $(p1.op()), 8(SP) + self.Emit("MOVQ", jit.Imm(int64(i)), jit.Ptr(_SP, 0)) // MOVQ $(i), (SP) + self.call_go(_F_println) +} + +var _runtime_writeBarrier uintptr = rt.GcwbAddr() + +//go:linkname gcWriteBarrierAX runtime.gcWriteBarrier +func gcWriteBarrierAX() + +var ( + _V_writeBarrier = jit.Imm(int64(_runtime_writeBarrier)) + + _F_gcWriteBarrierAX = jit.Func(gcWriteBarrierAX) +) + +func (self *_Assembler) WritePtrAX(i int, rec obj.Addr, saveDI bool) { + self.Emit("MOVQ", _V_writeBarrier, _R10) + self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + if saveDI { + self.save(_DI) + } + self.Emit("LEAQ", rec, _DI) + self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX + self.Rjmp("CALL", _R10) + if saveDI { + self.load(_DI) + } + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", _AX, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} + +func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool, saveAX bool) { + if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { + panic("rec contains AX!") + } + self.Emit("MOVQ", _V_writeBarrier, _R10) + self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + if saveAX { + self.Emit("XCHGQ", ptr, _AX) + } else { + self.Emit("MOVQ", ptr, _AX) + } + if saveDI { + self.save(_DI) + } + self.Emit("LEAQ", rec, _DI) + self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX + self.Rjmp("CALL", _R10) + if saveDI { + self.load(_DI) + } + if saveAX { + self.Emit("XCHGQ", ptr, _AX) + } + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", ptr, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/assembler_amd64_go117.go b/ihub/vendor/github.com/bytedance/sonic/decoder/assembler_amd64_go117.go new file mode 100644 index 0000000..8a70cff --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/assembler_amd64_go117.go @@ -0,0 +1,1922 @@ +//go:build go1.17 && !go1.21 +// +build go1.17,!go1.21 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `encoding/json` + `fmt` + `math` + `reflect` + `strconv` + `unsafe` + + `github.com/bytedance/sonic/internal/caching` + `github.com/bytedance/sonic/internal/jit` + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` + `github.com/twitchyliquid64/golang-asm/obj` + `github.com/twitchyliquid64/golang-asm/obj/x86` +) + +/** Register Allocations + * + * State Registers: + * + * %r13 : stack base + * %r10 : input pointer + * %r12 : input length + * %r11 : input cursor + * %r15 : value pointer + * + * Error Registers: + * + * %rax : error type register + * %rbx : error pointer register + */ + +/** Function Prototype & Stack Map + * + * func (s string, ic int, vp unsafe.Pointer, sb *_Stack, fv uint64, sv string) (rc int, err error) + * + * s.buf : (FP) + * s.len : 8(FP) + * ic : 16(FP) + * vp : 24(FP) + * sb : 32(FP) + * fv : 40(FP) + * sv : 56(FP) + * err.vt : 72(FP) + * err.vp : 80(FP) + */ + +const ( + _FP_args = 72 // 72 bytes to pass and spill register arguements + _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 +) + +const ( + _FP_offs = _FP_fargs + _FP_saves + _FP_locals + _FP_size = _FP_offs + 8 // 8 bytes for the parent frame pointer + _FP_base = _FP_size + 8 // 8 bytes for the return address +) + +const ( + _IM_null = 0x6c6c756e // 'null' + _IM_true = 0x65757274 // 'true' + _IM_alse = 0x65736c61 // 'alse' ('false' without the 'f') +) + +const ( + _BM_space = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n') +) + +const ( + _MODE_JSON = 1 << 3 // base64 mode +) + +const ( + _LB_error = "_error" + _LB_im_error = "_im_error" + _LB_eof_error = "_eof_error" + _LB_type_error = "_type_error" + _LB_field_error = "_field_error" + _LB_range_error = "_range_error" + _LB_stack_error = "_stack_error" + _LB_base64_error = "_base64_error" + _LB_unquote_error = "_unquote_error" + _LB_parsing_error = "_parsing_error" + _LB_parsing_error_v = "_parsing_error_v" + _LB_mismatch_error = "_mismatch_error" +) + +const ( + _LB_char_0_error = "_char_0_error" + _LB_char_1_error = "_char_1_error" + _LB_char_2_error = "_char_2_error" + _LB_char_3_error = "_char_3_error" + _LB_char_4_error = "_char_4_error" + _LB_char_m2_error = "_char_m2_error" + _LB_char_m3_error = "_char_m3_error" +) + +const ( + _LB_skip_one = "_skip_one" + _LB_skip_key_value = "_skip_key_value" +) + +var ( + _AX = jit.Reg("AX") + _BX = jit.Reg("BX") + _CX = jit.Reg("CX") + _DX = jit.Reg("DX") + _DI = jit.Reg("DI") + _SI = jit.Reg("SI") + _BP = jit.Reg("BP") + _SP = jit.Reg("SP") + _R8 = jit.Reg("R8") + _R9 = jit.Reg("R9") + _X0 = jit.Reg("X0") + _X1 = jit.Reg("X1") +) + +var ( + _IP = jit.Reg("R10") // saved on BP when callc + _IC = jit.Reg("R11") // saved on BX when call_c + _IL = jit.Reg("R12") + _ST = jit.Reg("R13") + _VP = jit.Reg("R15") +) + +var ( + _DF = jit.Reg("AX") // reuse AX in generic decoder for flags + _ET = jit.Reg("AX") + _EP = jit.Reg("BX") +) + + + +var ( + _ARG_s = _ARG_sp + _ARG_sp = jit.Ptr(_SP, _FP_base + 0) + _ARG_sl = jit.Ptr(_SP, _FP_base + 8) + _ARG_ic = jit.Ptr(_SP, _FP_base + 16) + _ARG_vp = jit.Ptr(_SP, _FP_base + 24) + _ARG_sb = jit.Ptr(_SP, _FP_base + 32) + _ARG_fv = jit.Ptr(_SP, _FP_base + 40) +) + +var ( + _ARG_sv = _ARG_sv_p + _ARG_sv_p = jit.Ptr(_SP, _FP_base + 48) + _ARG_sv_n = jit.Ptr(_SP, _FP_base + 56) + _ARG_vk = jit.Ptr(_SP, _FP_base + 64) +) + +var ( + _VAR_st = _VAR_st_Vt + _VAR_sr = jit.Ptr(_SP, _FP_fargs + _FP_saves) +) + +var ( + _VAR_st_Vt = jit.Ptr(_SP, _FP_fargs + _FP_saves + 0) + _VAR_st_Dv = jit.Ptr(_SP, _FP_fargs + _FP_saves + 8) + _VAR_st_Iv = jit.Ptr(_SP, _FP_fargs + _FP_saves + 16) + _VAR_st_Ep = jit.Ptr(_SP, _FP_fargs + _FP_saves + 24) + _VAR_st_Db = jit.Ptr(_SP, _FP_fargs + _FP_saves + 32) + _VAR_st_Dc = jit.Ptr(_SP, _FP_fargs + _FP_saves + 40) +) + +var ( + _VAR_ss_AX = jit.Ptr(_SP, _FP_fargs + _FP_saves + 48) + _VAR_ss_CX = jit.Ptr(_SP, _FP_fargs + _FP_saves + 56) + _VAR_ss_SI = jit.Ptr(_SP, _FP_fargs + _FP_saves + 64) + _VAR_ss_R8 = jit.Ptr(_SP, _FP_fargs + _FP_saves + 72) + _VAR_ss_R9 = jit.Ptr(_SP, _FP_fargs + _FP_saves + 80) +) + +var ( + _VAR_bs_p = jit.Ptr(_SP, _FP_fargs + _FP_saves + 88) + _VAR_bs_n = jit.Ptr(_SP, _FP_fargs + _FP_saves + 96) + _VAR_bs_LR = jit.Ptr(_SP, _FP_fargs + _FP_saves + 104) +) + +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_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 +) + +type _Assembler struct { + jit.BaseAssembler + p _Program + name string +} + +func newAssembler(p _Program) *_Assembler { + return new(_Assembler).Init(p) +} + +/** Assembler Interface **/ + +func (self *_Assembler) Load() _Decoder { + return ptodec(self.BaseAssembler.Load("decode_"+self.name, _FP_size, _FP_args, argPtrs, localPtrs)) +} + +func (self *_Assembler) Init(p _Program) *_Assembler { + self.p = p + self.BaseAssembler.Init(self.compile) + return self +} + +func (self *_Assembler) compile() { + self.prologue() + self.instrs() + self.epilogue() + self.copy_string() + self.escape_string() + self.escape_string_twice() + self.skip_one() + self.skip_key_value() + self.type_error() + self.mismatch_error() + self.field_error() + self.range_error() + self.stack_error() + self.base64_error() + self.parsing_error() +} + +/** Assembler Stages **/ + +var _OpFuncTab = [256]func(*_Assembler, *_Instr) { + _OP_any : (*_Assembler)._asm_OP_any, + _OP_dyn : (*_Assembler)._asm_OP_dyn, + _OP_str : (*_Assembler)._asm_OP_str, + _OP_bin : (*_Assembler)._asm_OP_bin, + _OP_bool : (*_Assembler)._asm_OP_bool, + _OP_num : (*_Assembler)._asm_OP_num, + _OP_i8 : (*_Assembler)._asm_OP_i8, + _OP_i16 : (*_Assembler)._asm_OP_i16, + _OP_i32 : (*_Assembler)._asm_OP_i32, + _OP_i64 : (*_Assembler)._asm_OP_i64, + _OP_u8 : (*_Assembler)._asm_OP_u8, + _OP_u16 : (*_Assembler)._asm_OP_u16, + _OP_u32 : (*_Assembler)._asm_OP_u32, + _OP_u64 : (*_Assembler)._asm_OP_u64, + _OP_f32 : (*_Assembler)._asm_OP_f32, + _OP_f64 : (*_Assembler)._asm_OP_f64, + _OP_unquote : (*_Assembler)._asm_OP_unquote, + _OP_nil_1 : (*_Assembler)._asm_OP_nil_1, + _OP_nil_2 : (*_Assembler)._asm_OP_nil_2, + _OP_nil_3 : (*_Assembler)._asm_OP_nil_3, + _OP_deref : (*_Assembler)._asm_OP_deref, + _OP_index : (*_Assembler)._asm_OP_index, + _OP_is_null : (*_Assembler)._asm_OP_is_null, + _OP_is_null_quote : (*_Assembler)._asm_OP_is_null_quote, + _OP_map_init : (*_Assembler)._asm_OP_map_init, + _OP_map_key_i8 : (*_Assembler)._asm_OP_map_key_i8, + _OP_map_key_i16 : (*_Assembler)._asm_OP_map_key_i16, + _OP_map_key_i32 : (*_Assembler)._asm_OP_map_key_i32, + _OP_map_key_i64 : (*_Assembler)._asm_OP_map_key_i64, + _OP_map_key_u8 : (*_Assembler)._asm_OP_map_key_u8, + _OP_map_key_u16 : (*_Assembler)._asm_OP_map_key_u16, + _OP_map_key_u32 : (*_Assembler)._asm_OP_map_key_u32, + _OP_map_key_u64 : (*_Assembler)._asm_OP_map_key_u64, + _OP_map_key_f32 : (*_Assembler)._asm_OP_map_key_f32, + _OP_map_key_f64 : (*_Assembler)._asm_OP_map_key_f64, + _OP_map_key_str : (*_Assembler)._asm_OP_map_key_str, + _OP_map_key_utext : (*_Assembler)._asm_OP_map_key_utext, + _OP_map_key_utext_p : (*_Assembler)._asm_OP_map_key_utext_p, + _OP_array_skip : (*_Assembler)._asm_OP_array_skip, + _OP_array_clear : (*_Assembler)._asm_OP_array_clear, + _OP_array_clear_p : (*_Assembler)._asm_OP_array_clear_p, + _OP_slice_init : (*_Assembler)._asm_OP_slice_init, + _OP_slice_append : (*_Assembler)._asm_OP_slice_append, + _OP_object_skip : (*_Assembler)._asm_OP_object_skip, + _OP_object_next : (*_Assembler)._asm_OP_object_next, + _OP_struct_field : (*_Assembler)._asm_OP_struct_field, + _OP_unmarshal : (*_Assembler)._asm_OP_unmarshal, + _OP_unmarshal_p : (*_Assembler)._asm_OP_unmarshal_p, + _OP_unmarshal_text : (*_Assembler)._asm_OP_unmarshal_text, + _OP_unmarshal_text_p : (*_Assembler)._asm_OP_unmarshal_text_p, + _OP_lspace : (*_Assembler)._asm_OP_lspace, + _OP_match_char : (*_Assembler)._asm_OP_match_char, + _OP_check_char : (*_Assembler)._asm_OP_check_char, + _OP_load : (*_Assembler)._asm_OP_load, + _OP_save : (*_Assembler)._asm_OP_save, + _OP_drop : (*_Assembler)._asm_OP_drop, + _OP_drop_2 : (*_Assembler)._asm_OP_drop_2, + _OP_recurse : (*_Assembler)._asm_OP_recurse, + _OP_goto : (*_Assembler)._asm_OP_goto, + _OP_switch : (*_Assembler)._asm_OP_switch, + _OP_check_char_0 : (*_Assembler)._asm_OP_check_char_0, + _OP_dismatch_err : (*_Assembler)._asm_OP_dismatch_err, + _OP_go_skip : (*_Assembler)._asm_OP_go_skip, + _OP_add : (*_Assembler)._asm_OP_add, + _OP_debug : (*_Assembler)._asm_OP_debug, +} + +func (self *_Assembler) _asm_OP_debug(_ *_Instr) { + self.Byte(0xcc) +} + +func (self *_Assembler) instr(v *_Instr) { + if fn := _OpFuncTab[v.op()]; fn != nil { + fn(self, v) + } else { + panic(fmt.Sprintf("invalid opcode: %d", v.op())) + } +} + +func (self *_Assembler) instrs() { + for i, v := range self.p { + self.Mark(i) + self.instr(&v) + self.debug_instr(i, &v) + } +} + +func (self *_Assembler) epilogue() { + self.Mark(len(self.p)) + self.Emit("XORL", _EP, _EP) // XORL EP, EP + self.Emit("MOVQ", _VAR_et, _ET) // MOVQ VAR_et, ET + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ", _LB_mismatch_error) // JNZ _LB_mismatch_error + self.Link(_LB_error) // _error: + self.Emit("MOVQ", _EP, _CX) // MOVQ BX, CX + self.Emit("MOVQ", _ET, _BX) // MOVQ AX, BX + self.Emit("MOVQ", _IC, _AX) // MOVQ IC, AX + self.Emit("MOVQ", jit.Imm(0), _ARG_sp) // MOVQ $0, sv.p<>+48(FP) + self.Emit("MOVQ", jit.Imm(0), _ARG_vp) // MOVQ $0, sv.p<>+48(FP) + self.Emit("MOVQ", jit.Imm(0), _ARG_sv_p) // MOVQ $0, sv.p<>+48(FP) + self.Emit("MOVQ", jit.Imm(0), _ARG_vk) // MOVQ $0, vk<>+64(FP) + self.Emit("MOVQ", jit.Ptr(_SP, _FP_offs), _BP) // MOVQ _FP_offs(SP), BP + self.Emit("ADDQ", jit.Imm(_FP_size), _SP) // ADDQ $_FP_size, SP + self.Emit("RET") // RET +} + +func (self *_Assembler) prologue() { + self.Emit("SUBQ", jit.Imm(_FP_size), _SP) // SUBQ $_FP_size, SP + self.Emit("MOVQ", _BP, jit.Ptr(_SP, _FP_offs)) // MOVQ BP, _FP_offs(SP) + self.Emit("LEAQ", jit.Ptr(_SP, _FP_offs), _BP) // LEAQ _FP_offs(SP), BP + self.Emit("MOVQ", _AX, _ARG_sp) // MOVQ AX, s.p<>+0(FP) + self.Emit("MOVQ", _AX, _IP) // MOVQ AX, IP + self.Emit("MOVQ", _BX, _ARG_sl) // MOVQ BX, s.l<>+8(FP) + self.Emit("MOVQ", _BX, _IL) // MOVQ BX, IL + self.Emit("MOVQ", _CX, _ARG_ic) // MOVQ CX, ic<>+16(FP) + self.Emit("MOVQ", _CX, _IC) // MOVQ CX, IC + self.Emit("MOVQ", _DI, _ARG_vp) // MOVQ DI, vp<>+24(FP) + self.Emit("MOVQ", _DI, _VP) // MOVQ DI, VP + self.Emit("MOVQ", _SI, _ARG_sb) // MOVQ SI, sb<>+32(FP) + self.Emit("MOVQ", _SI, _ST) // MOVQ SI, ST + self.Emit("MOVQ", _R8, _ARG_fv) // MOVQ R8, fv<>+40(FP) + self.Emit("MOVQ", jit.Imm(0), _ARG_sv_p) // MOVQ $0, sv.p<>+48(FP) + self.Emit("MOVQ", jit.Imm(0), _ARG_sv_n) // MOVQ $0, sv.n<>+56(FP) + self.Emit("MOVQ", jit.Imm(0), _ARG_vk) // MOVQ $0, vk<>+64(FP) + self.Emit("MOVQ", jit.Imm(0), _VAR_et) // MOVQ $0, et<>+120(FP) + // initialize digital buffer first + self.Emit("MOVQ", jit.Imm(_MaxDigitNums), _VAR_st_Dc) // MOVQ $_MaxDigitNums, ss.Dcap + self.Emit("LEAQ", jit.Ptr(_ST, _DbufOffset), _AX) // LEAQ _DbufOffset(ST), AX + self.Emit("MOVQ", _AX, _VAR_st_Db) // MOVQ AX, ss.Dbuf +} + +/** Function Calling Helpers **/ + +var ( + _REG_go = []obj.Addr { _ST, _VP, _IP, _IL, _IC } + _REG_rt = []obj.Addr { _ST, _VP, _IP, _IL, _IC, _IL } +) + +func (self *_Assembler) save(r ...obj.Addr) { + for i, v := range r { + if i > _FP_saves / 8 - 1 { + panic("too many registers to save") + } else { + self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs + int64(i) * 8)) + } + } +} + +func (self *_Assembler) load(r ...obj.Addr) { + for i, v := range r { + if i > _FP_saves / 8 - 1 { + panic("too many registers to load") + } else { + self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs + int64(i) * 8), v) + } + } +} + +func (self *_Assembler) call(fn obj.Addr) { + self.Emit("MOVQ", fn, _R9) // MOVQ ${fn}, R11 + self.Rjmp("CALL", _R9) // CALL R11 +} + +func (self *_Assembler) call_go(fn obj.Addr) { + self.save(_REG_go...) // SAVE $REG_go + self.call(fn) + self.load(_REG_go...) // LOAD $REG_go +} + +func (self *_Assembler) callc(fn obj.Addr) { + self.Emit("XCHGQ", _IP, _BP) + self.call(fn) + self.Emit("XCHGQ", _IP, _BP) +} + +func (self *_Assembler) call_c(fn obj.Addr) { + self.Emit("XCHGQ", _IC, _BX) + self.callc(fn) + self.Emit("XCHGQ", _IC, _BX) +} + +func (self *_Assembler) call_sf(fn obj.Addr) { + self.Emit("LEAQ", _ARG_s, _DI) // LEAQ s<>+0(FP), DI + self.Emit("MOVQ", _IC, _ARG_ic) // MOVQ IC, ic<>+16(FP) + self.Emit("LEAQ", _ARG_ic, _SI) // LEAQ ic<>+16(FP), SI + self.Emit("LEAQ", jit.Ptr(_ST, _FsmOffset), _DX) // LEAQ _FsmOffset(ST), DX + self.Emit("MOVQ", _ARG_fv, _CX) + self.callc(fn) + self.Emit("MOVQ", _ARG_ic, _IC) // MOVQ ic<>+16(FP), IC +} + +func (self *_Assembler) call_vf(fn obj.Addr) { + self.Emit("LEAQ", _ARG_s, _DI) // LEAQ s<>+0(FP), DI + self.Emit("MOVQ", _IC, _ARG_ic) // MOVQ IC, ic<>+16(FP) + self.Emit("LEAQ", _ARG_ic, _SI) // LEAQ ic<>+16(FP), SI + self.Emit("LEAQ", _VAR_st, _DX) // LEAQ st, DX + self.callc(fn) + self.Emit("MOVQ", _ARG_ic, _IC) // MOVQ ic<>+16(FP), IC +} + +/** Assembler Error Handlers **/ + +var ( + _F_convT64 = jit.Func(convT64) + _F_error_wrap = jit.Func(error_wrap) + _F_error_type = jit.Func(error_type) + _F_error_field = jit.Func(error_field) + _F_error_value = jit.Func(error_value) + _F_error_mismatch = jit.Func(error_mismatch) +) + +var ( + _I_int8 , _T_int8 = rtype(reflect.TypeOf(int8(0))) + _I_int16 , _T_int16 = rtype(reflect.TypeOf(int16(0))) + _I_int32 , _T_int32 = rtype(reflect.TypeOf(int32(0))) + _I_uint8 , _T_uint8 = rtype(reflect.TypeOf(uint8(0))) + _I_uint16 , _T_uint16 = rtype(reflect.TypeOf(uint16(0))) + _I_uint32 , _T_uint32 = rtype(reflect.TypeOf(uint32(0))) + _I_float32 , _T_float32 = rtype(reflect.TypeOf(float32(0))) +) + +var ( + _T_error = rt.UnpackType(errorType) + _I_base64_CorruptInputError = jit.Itab(_T_error, base64CorruptInputError) +) + +var ( + _V_stackOverflow = jit.Imm(int64(uintptr(unsafe.Pointer(&stackOverflow)))) + _I_json_UnsupportedValueError = jit.Itab(_T_error, reflect.TypeOf(new(json.UnsupportedValueError))) +) + +func (self *_Assembler) type_error() { + self.Link(_LB_type_error) // _type_error: + self.call_go(_F_error_type) // CALL_GO error_type + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) mismatch_error() { + self.Link(_LB_mismatch_error) // _type_error: + self.Emit("MOVQ", _ARG_sp, _AX) + self.Emit("MOVQ", _ARG_sl, _BX) + self.Emit("MOVQ", _VAR_ic, _CX) + self.Emit("MOVQ", _VAR_et, _DI) + self.call_go(_F_error_mismatch) // CALL_GO error_type + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) field_error() { + self.Link(_LB_field_error) // _field_error: + self.Emit("MOVQ", _ARG_sv_p, _AX) // MOVQ sv.p, AX + self.Emit("MOVQ", _ARG_sv_n, _BX) // MOVQ sv.n, BX + self.call_go(_F_error_field) // CALL_GO error_field + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) range_error() { + self.Link(_LB_range_error) // _range_error: + self.Emit("MOVQ", _ET, _CX) // MOVQ ET, CX + self.slice_from(_VAR_st_Ep, 0) // SLICE st.Ep, $0 + self.Emit("MOVQ", _DI, _AX) // MOVQ DI, AX + self.Emit("MOVQ", _EP, _DI) // MOVQ EP, DI + self.Emit("MOVQ", _SI, _BX) // MOVQ SI, BX + self.call_go(_F_error_value) // CALL_GO error_value + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) stack_error() { + self.Link(_LB_stack_error) // _stack_error: + self.Emit("MOVQ", _V_stackOverflow, _EP) // MOVQ ${_V_stackOverflow}, EP + self.Emit("MOVQ", _I_json_UnsupportedValueError, _ET) // MOVQ ${_I_json_UnsupportedValueError}, ET + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) base64_error() { + self.Link(_LB_base64_error) + self.Emit("NEGQ", _AX) // NEGQ AX + self.Emit("SUBQ", jit.Imm(1), _AX) // SUBQ $1, AX + self.call_go(_F_convT64) // CALL_GO convT64 + self.Emit("MOVQ", _AX, _EP) // MOVQ AX, EP + self.Emit("MOVQ", _I_base64_CorruptInputError, _ET) // MOVQ ${itab(base64.CorruptInputError)}, ET + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) parsing_error() { + self.Link(_LB_eof_error) // _eof_error: + self.Emit("MOVQ" , _IL, _IC) // MOVQ IL, IC + self.Emit("MOVL" , jit.Imm(int64(types.ERR_EOF)), _EP) // MOVL ${types.ERR_EOF}, EP + self.Sjmp("JMP" , _LB_parsing_error) // JMP _parsing_error + self.Link(_LB_unquote_error) // _unquote_error: + self.Emit("SUBQ" , _VAR_sr, _SI) // SUBQ sr, SI + self.Emit("SUBQ" , _SI, _IC) // SUBQ IL, IC + self.Link(_LB_parsing_error_v) // _parsing_error_v: + self.Emit("MOVQ" , _AX, _EP) // MOVQ AX, EP + self.Emit("NEGQ" , _EP) // NEGQ EP + self.Sjmp("JMP" , _LB_parsing_error) // JMP _parsing_error + self.Link(_LB_char_m3_error) // _char_m3_error: + self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC + self.Link(_LB_char_m2_error) // _char_m2_error: + self.Emit("SUBQ" , jit.Imm(2), _IC) // SUBQ $2, IC + self.Sjmp("JMP" , _LB_char_0_error) // JMP _char_0_error + self.Link(_LB_im_error) // _im_error: + self.Emit("CMPB" , _CX, jit.Sib(_IP, _IC, 1, 0)) // CMPB CX, (IP)(IC) + self.Sjmp("JNE" , _LB_char_0_error) // JNE _char_0_error + self.Emit("SHRL" , jit.Imm(8), _CX) // SHRL $8, CX + self.Emit("CMPB" , _CX, jit.Sib(_IP, _IC, 1, 1)) // CMPB CX, 1(IP)(IC) + self.Sjmp("JNE" , _LB_char_1_error) // JNE _char_1_error + self.Emit("SHRL" , jit.Imm(8), _CX) // SHRL $8, CX + self.Emit("CMPB" , _CX, jit.Sib(_IP, _IC, 1, 2)) // CMPB CX, 2(IP)(IC) + self.Sjmp("JNE" , _LB_char_2_error) // JNE _char_2_error + self.Sjmp("JMP" , _LB_char_3_error) // JNE _char_3_error + self.Link(_LB_char_4_error) // _char_4_error: + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Link(_LB_char_3_error) // _char_3_error: + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Link(_LB_char_2_error) // _char_2_error: + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Link(_LB_char_1_error) // _char_1_error: + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Link(_LB_char_0_error) // _char_0_error: + self.Emit("MOVL" , jit.Imm(int64(types.ERR_INVALID_CHAR)), _EP) // MOVL ${types.ERR_INVALID_CHAR}, EP + self.Link(_LB_parsing_error) // _parsing_error: + self.Emit("MOVQ" , _EP, _DI) // MOVQ EP, DI + self.Emit("MOVQ", _ARG_sp, _AX) // MOVQ sp, AX + self.Emit("MOVQ", _ARG_sl, _BX) // MOVQ sl, BX + self.Emit("MOVQ" , _IC, _CX) // MOVQ IC, CX + self.call_go(_F_error_wrap) // CALL_GO error_wrap + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) _asm_OP_dismatch_err(p *_Instr) { + self.Emit("MOVQ", _IC, _VAR_ic) + self.Emit("MOVQ", jit.Type(p.vt()), _ET) + self.Emit("MOVQ", _ET, _VAR_et) +} + +func (self *_Assembler) _asm_OP_go_skip(p *_Instr) { + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Xref(p.vi(), 4) + // self.Byte(0xcc) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_one) // JMP _skip_one +} + +func (self *_Assembler) skip_one() { + self.Link(_LB_skip_one) // _skip: + self.Emit("MOVQ", _VAR_ic, _IC) // MOVQ _VAR_ic, IC + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v + self.Emit("MOVQ" , _VAR_pc, _R9) // MOVQ pc, R9 + // self.Byte(0xcc) + self.Rjmp("JMP" , _R9) // JMP (R9) +} + +func (self *_Assembler) skip_key_value() { + self.Link(_LB_skip_key_value) // _skip: + // skip the key + self.Emit("MOVQ", _VAR_ic, _IC) // MOVQ _VAR_ic, IC + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v + // match char ':' + self.lspace("_global_1") + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(':')) + self.Sjmp("JNE" , _LB_parsing_error_v) // JNE _parse_error_v + self.Emit("ADDQ", jit.Imm(1), _IC) // ADDQ $1, IC + self.lspace("_global_2") + // skip the value + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v + // jump back to specified address + self.Emit("MOVQ" , _VAR_pc, _R9) // MOVQ pc, R9 + self.Rjmp("JMP" , _R9) // JMP (R9) +} + + +/** Memory Management Routines **/ + +var ( + _T_byte = jit.Type(byteType) + _F_mallocgc = jit.Func(mallocgc) +) + +func (self *_Assembler) malloc_AX(nb obj.Addr, ret obj.Addr) { + self.Emit("MOVQ", nb, _AX) // MOVQ ${nb}, AX + self.Emit("MOVQ", _T_byte, _BX) // MOVQ ${type(byte)}, BX + self.Emit("XORL", _CX, _CX) // XORL CX, CX + self.call_go(_F_mallocgc) // CALL_GO mallocgc + self.Emit("MOVQ", _AX, ret) // MOVQ AX, ${ret} +} + +func (self *_Assembler) valloc(vt reflect.Type, ret obj.Addr) { + self.Emit("MOVQ", jit.Imm(int64(vt.Size())), _AX) // MOVQ ${vt.Size()}, AX + self.Emit("MOVQ", jit.Type(vt), _BX) // MOVQ ${vt}, BX + self.Emit("MOVB", jit.Imm(1), _CX) // MOVB $1, CX + self.call_go(_F_mallocgc) // CALL_GO mallocgc + self.Emit("MOVQ", _AX, ret) // MOVQ AX, ${ret} +} + +func (self *_Assembler) valloc_AX(vt reflect.Type) { + self.Emit("MOVQ", jit.Imm(int64(vt.Size())), _AX) // MOVQ ${vt.Size()}, AX + self.Emit("MOVQ", jit.Type(vt), _BX) // MOVQ ${vt}, BX + self.Emit("MOVB", jit.Imm(1), _CX) // MOVB $1, CX + self.call_go(_F_mallocgc) // CALL_GO mallocgc +} + +func (self *_Assembler) vfollow(vt reflect.Type) { + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _AX) // MOVQ (VP), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNZ" , "_end_{n}") // JNZ _end_{n} + self.valloc_AX(vt) // VALLOC ${vt}, AX + self.WritePtrAX(1, jit.Ptr(_VP, 0), true) // MOVQ AX, (VP) + self.Link("_end_{n}") // _end_{n}: + self.Emit("MOVQ" , _AX, _VP) // MOVQ AX, VP +} + +/** Value Parsing Routines **/ + +var ( + _F_vstring = jit.Imm(int64(native.S_vstring)) + _F_vnumber = jit.Imm(int64(native.S_vnumber)) + _F_vsigned = jit.Imm(int64(native.S_vsigned)) + _F_vunsigned = jit.Imm(int64(native.S_vunsigned)) +) + +func (self *_Assembler) check_err(vt reflect.Type, pin string, pin2 int) { + self.Emit("MOVQ" , _VAR_st_Vt, _AX) // MOVQ st.Vt, AX + self.Emit("TESTQ", _AX, _AX) // CMPQ AX, ${native.V_STRING} + // try to skip the value + if vt != nil { + self.Sjmp("JNS" , "_check_err_{n}") // JNE _parsing_error_v + self.Emit("MOVQ", jit.Type(vt), _ET) + self.Emit("MOVQ", _ET, _VAR_et) + if pin2 != -1 { + self.Emit("SUBQ", jit.Imm(1), _BX) + self.Emit("MOVQ", _BX, _VAR_ic) + self.Byte(0x4c , 0x8d, 0x0d) // LEAQ (PC), R9 + self.Xref(pin2, 4) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_key_value) + } else { + self.Emit("MOVQ", _BX, _VAR_ic) + self.Byte(0x4c , 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref(pin, 4) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_one) + } + self.Link("_check_err_{n}") + } else { + self.Sjmp("JS" , _LB_parsing_error_v) // JNE _parsing_error_v + } +} + +func (self *_Assembler) check_eof(d int64) { + if d == 1 { + self.Emit("CMPQ", _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , _LB_eof_error) // JAE _eof_error + } else { + self.Emit("LEAQ", jit.Ptr(_IC, d), _AX) // LEAQ ${d}(IC), AX + self.Emit("CMPQ", _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , _LB_eof_error) // JA _eof_error + } +} + + +func (self *_Assembler) parse_string() { + self.Emit("MOVQ", _ARG_fv, _CX) + self.call_vf(_F_vstring) + self.check_err(nil, "", -1) +} + +func (self *_Assembler) parse_number(vt reflect.Type, pin string, pin2 int) { + self.Emit("MOVQ", _IC, _BX) // save ic when call native func + self.call_vf(_F_vnumber) + self.check_err(vt, pin, pin2) +} + +func (self *_Assembler) parse_signed(vt reflect.Type, pin string, pin2 int) { + self.Emit("MOVQ", _IC, _BX) // save ic when call native func + self.call_vf(_F_vsigned) + self.check_err(vt, pin, pin2) +} + +func (self *_Assembler) parse_unsigned(vt reflect.Type, pin string, pin2 int) { + self.Emit("MOVQ", _IC, _BX) // save ic when call native func + self.call_vf(_F_vunsigned) + self.check_err(vt, pin, pin2) +} + +// Pointer: DI, Size: SI, Return: R9 +func (self *_Assembler) copy_string() { + self.Link("_copy_string") + self.Emit("MOVQ", _DI, _VAR_bs_p) + self.Emit("MOVQ", _SI, _VAR_bs_n) + self.Emit("MOVQ", _R9, _VAR_bs_LR) + self.malloc_AX(_SI, _ARG_sv_p) + self.Emit("MOVQ", _VAR_bs_p, _BX) + self.Emit("MOVQ", _VAR_bs_n, _CX) + self.call_go(_F_memmove) + self.Emit("MOVQ", _ARG_sv_p, _DI) + self.Emit("MOVQ", _VAR_bs_n, _SI) + self.Emit("MOVQ", _VAR_bs_LR, _R9) + self.Rjmp("JMP", _R9) +} + +// Pointer: DI, Size: SI, Return: R9 +func (self *_Assembler) escape_string() { + self.Link("_escape_string") + self.Emit("MOVQ" , _DI, _VAR_bs_p) + self.Emit("MOVQ" , _SI, _VAR_bs_n) + self.Emit("MOVQ" , _R9, _VAR_bs_LR) + self.malloc_AX(_SI, _DX) // MALLOC SI, DX + self.Emit("MOVQ" , _DX, _ARG_sv_p) + self.Emit("MOVQ" , _VAR_bs_p, _DI) + self.Emit("MOVQ" , _VAR_bs_n, _SI) + self.Emit("LEAQ" , _VAR_sr, _CX) // LEAQ sr, CX + self.Emit("XORL" , _R8, _R8) // XORL R8, R8 + self.Emit("BTQ" , jit.Imm(_F_disable_urc), _ARG_fv) // BTQ ${_F_disable_urc}, fv + self.Emit("SETCC", _R8) // SETCC R8 + self.Emit("SHLQ" , jit.Imm(types.B_UNICODE_REPLACE), _R8) // SHLQ ${types.B_UNICODE_REPLACE}, R8 + self.call_c(_F_unquote) // CALL unquote + self.Emit("MOVQ" , _VAR_bs_n, _SI) // MOVQ ${n}, SI + self.Emit("ADDQ" , jit.Imm(1), _SI) // ADDQ $1, SI + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_unquote_error) // JS _unquote_error + self.Emit("MOVQ" , _AX, _SI) + self.Emit("MOVQ" , _ARG_sv_p, _DI) + self.Emit("MOVQ" , _VAR_bs_LR, _R9) + self.Rjmp("JMP", _R9) +} + +func (self *_Assembler) escape_string_twice() { + self.Link("_escape_string_twice") + self.Emit("MOVQ" , _DI, _VAR_bs_p) + self.Emit("MOVQ" , _SI, _VAR_bs_n) + self.Emit("MOVQ" , _R9, _VAR_bs_LR) + self.malloc_AX(_SI, _DX) // MALLOC SI, DX + self.Emit("MOVQ" , _DX, _ARG_sv_p) + self.Emit("MOVQ" , _VAR_bs_p, _DI) + self.Emit("MOVQ" , _VAR_bs_n, _SI) + self.Emit("LEAQ" , _VAR_sr, _CX) // LEAQ sr, CX + self.Emit("MOVL" , jit.Imm(types.F_DOUBLE_UNQUOTE), _R8) // MOVL ${types.F_DOUBLE_UNQUOTE}, R8 + self.Emit("BTQ" , jit.Imm(_F_disable_urc), _ARG_fv) // BTQ ${_F_disable_urc}, AX + self.Emit("XORL" , _AX, _AX) // XORL AX, AX + self.Emit("SETCC", _AX) // SETCC AX + self.Emit("SHLQ" , jit.Imm(types.B_UNICODE_REPLACE), _AX) // SHLQ ${types.B_UNICODE_REPLACE}, AX + self.Emit("ORQ" , _AX, _R8) // ORQ AX, R8 + self.call_c(_F_unquote) // CALL unquote + self.Emit("MOVQ" , _VAR_bs_n, _SI) // MOVQ ${n}, SI + self.Emit("ADDQ" , jit.Imm(3), _SI) // ADDQ $3, SI + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_unquote_error) // JS _unquote_error + self.Emit("MOVQ" , _AX, _SI) + self.Emit("MOVQ" , _ARG_sv_p, _DI) + self.Emit("MOVQ" , _VAR_bs_LR, _R9) + self.Rjmp("JMP", _R9) +} + +/** Range Checking Routines **/ + +var ( + _V_max_f32 = jit.Imm(int64(uintptr(unsafe.Pointer(_Vp_max_f32)))) + _V_min_f32 = jit.Imm(int64(uintptr(unsafe.Pointer(_Vp_min_f32)))) +) + +var ( + _Vp_max_f32 = new(float64) + _Vp_min_f32 = new(float64) +) + +func init() { + *_Vp_max_f32 = math.MaxFloat32 + *_Vp_min_f32 = -math.MaxFloat32 +} + +func (self *_Assembler) range_single_X0() { + self.Emit("MOVSD" , _VAR_st_Dv, _X0) // MOVSD st.Dv, X0 + self.Emit("MOVQ" , _V_max_f32, _CX) // MOVQ _max_f32, CX + self.Emit("MOVQ" , jit.Gitab(_I_float32), _ET) // MOVQ ${itab(float32)}, ET + self.Emit("MOVQ" , jit.Gtype(_T_float32), _EP) // MOVQ ${type(float32)}, EP + self.Emit("UCOMISD" , jit.Ptr(_CX, 0), _X0) // UCOMISD (CX), X0 + self.Sjmp("JA" , _LB_range_error) // JA _range_error + self.Emit("MOVQ" , _V_min_f32, _CX) // MOVQ _min_f32, CX + self.Emit("MOVSD" , jit.Ptr(_CX, 0), _X1) // MOVSD (CX), X1 + self.Emit("UCOMISD" , _X0, _X1) // UCOMISD X0, X1 + self.Sjmp("JA" , _LB_range_error) // JA _range_error + self.Emit("CVTSD2SS", _X0, _X0) // CVTSD2SS X0, X0 +} + +func (self *_Assembler) range_signed_CX(i *rt.GoItab, t *rt.GoType, a int64, b int64) { + self.Emit("MOVQ", _VAR_st_Iv, _CX) // MOVQ st.Iv, CX + self.Emit("MOVQ", jit.Gitab(i), _ET) // MOVQ ${i}, ET + self.Emit("MOVQ", jit.Gtype(t), _EP) // MOVQ ${t}, EP + self.Emit("CMPQ", _CX, jit.Imm(a)) // CMPQ CX, ${a} + self.Sjmp("JL" , _LB_range_error) // JL _range_error + self.Emit("CMPQ", _CX, jit.Imm(b)) // CMPQ CX, ${B} + self.Sjmp("JG" , _LB_range_error) // JG _range_error +} + +func (self *_Assembler) range_unsigned_CX(i *rt.GoItab, t *rt.GoType, v uint64) { + self.Emit("MOVQ" , _VAR_st_Iv, _CX) // MOVQ st.Iv, CX + self.Emit("MOVQ" , jit.Gitab(i), _ET) // MOVQ ${i}, ET + self.Emit("MOVQ" , jit.Gtype(t), _EP) // MOVQ ${t}, EP + self.Emit("TESTQ", _CX, _CX) // TESTQ CX, CX + self.Sjmp("JS" , _LB_range_error) // JS _range_error + self.Emit("CMPQ" , _CX, jit.Imm(int64(v))) // CMPQ CX, ${a} + self.Sjmp("JA" , _LB_range_error) // JA _range_error +} + +/** String Manipulating Routines **/ + +var ( + _F_unquote = jit.Imm(int64(native.S_unquote)) +) + +func (self *_Assembler) slice_from(p obj.Addr, d int64) { + self.Emit("MOVQ", p, _SI) // MOVQ ${p}, SI + self.slice_from_r(_SI, d) // SLICE_R SI, ${d} +} + +func (self *_Assembler) slice_from_r(p obj.Addr, d int64) { + self.Emit("LEAQ", jit.Sib(_IP, p, 1, 0), _DI) // LEAQ (IP)(${p}), DI + self.Emit("NEGQ", p) // NEGQ ${p} + self.Emit("LEAQ", jit.Sib(_IC, p, 1, d), _SI) // LEAQ d(IC)(${p}), SI +} + +func (self *_Assembler) unquote_once(p obj.Addr, n obj.Addr, stack bool, copy bool) { + self.slice_from(_VAR_st_Iv, -1) // SLICE st.Iv, $-1 + self.Emit("CMPQ", _VAR_st_Ep, jit.Imm(-1)) // CMPQ st.Ep, $-1 + self.Sjmp("JE" , "_noescape_{n}") // JE _escape_{n} + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_unquote_once_write_{n}", 4) + self.Sjmp("JMP" , "_escape_string") + self.Link("_noescape_{n}") + if copy { + self.Emit("BTQ" , jit.Imm(_F_copy_string), _ARG_fv) + self.Sjmp("JNC", "_unquote_once_write_{n}") + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_unquote_once_write_{n}", 4) + self.Sjmp("JMP", "_copy_string") + } + self.Link("_unquote_once_write_{n}") + self.Emit("MOVQ", _SI, n) // MOVQ SI, ${n} + if stack { + self.Emit("MOVQ", _DI, p) + } else { + self.WriteRecNotAX(10, _DI, p, false, false) + } +} + +func (self *_Assembler) unquote_twice(p obj.Addr, n obj.Addr, stack bool) { + self.Emit("CMPQ" , _VAR_st_Ep, jit.Imm(-1)) // CMPQ st.Ep, $-1 + self.Sjmp("JE" , _LB_eof_error) // JE _eof_error + self.Emit("CMPB" , jit.Sib(_IP, _IC, 1, -3), jit.Imm('\\')) // CMPB -3(IP)(IC), $'\\' + self.Sjmp("JNE" , _LB_char_m3_error) // JNE _char_m3_error + self.Emit("CMPB" , jit.Sib(_IP, _IC, 1, -2), jit.Imm('"')) // CMPB -2(IP)(IC), $'"' + self.Sjmp("JNE" , _LB_char_m2_error) // JNE _char_m2_error + self.slice_from(_VAR_st_Iv, -3) // SLICE st.Iv, $-3 + self.Emit("MOVQ" , _SI, _AX) // MOVQ SI, AX + self.Emit("ADDQ" , _VAR_st_Iv, _AX) // ADDQ st.Iv, AX + self.Emit("CMPQ" , _VAR_st_Ep, _AX) // CMPQ st.Ep, AX + self.Sjmp("JE" , "_noescape_{n}") // JE _noescape_{n} + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_unquote_twice_write_{n}", 4) + self.Sjmp("JMP" , "_escape_string_twice") + self.Link("_noescape_{n}") // _noescape_{n}: + self.Emit("BTQ" , jit.Imm(_F_copy_string), _ARG_fv) + self.Sjmp("JNC", "_unquote_twice_write_{n}") + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_unquote_twice_write_{n}", 4) + self.Sjmp("JMP", "_copy_string") + self.Link("_unquote_twice_write_{n}") + self.Emit("MOVQ" , _SI, n) // MOVQ SI, ${n} + if stack { + self.Emit("MOVQ", _DI, p) + } else { + self.WriteRecNotAX(12, _DI, p, false, false) + } + self.Link("_unquote_twice_end_{n}") +} + +/** Memory Clearing Routines **/ + +var ( + _F_memclrHasPointers = jit.Func(memclrHasPointers) + _F_memclrNoHeapPointers = jit.Func(memclrNoHeapPointers) +) + +func (self *_Assembler) mem_clear_fn(ptrfree bool) { + if !ptrfree { + self.call_go(_F_memclrHasPointers) + } else { + self.call_go(_F_memclrNoHeapPointers) + } +} + +func (self *_Assembler) mem_clear_rem(size int64, ptrfree bool) { + self.Emit("MOVQ", jit.Imm(size), _BX) // MOVQ ${size}, BX + self.Emit("MOVQ", jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, 0), _AX) // MOVQ (ST)(AX), AX + self.Emit("SUBQ", _VP, _AX) // SUBQ VP, AX + self.Emit("ADDQ", _AX, _BX) // ADDQ AX, BX + self.Emit("MOVQ", _VP, _AX) // MOVQ VP, (SP) + self.mem_clear_fn(ptrfree) // CALL_GO memclr{Has,NoHeap}Pointers +} + +/** Map Assigning Routines **/ + +var ( + _F_mapassign = jit.Func(mapassign) + _F_mapassign_fast32 = jit.Func(mapassign_fast32) + _F_mapassign_faststr = jit.Func(mapassign_faststr) + _F_mapassign_fast64ptr = jit.Func(mapassign_fast64ptr) +) + +var ( + _F_decodeJsonUnmarshaler obj.Addr + _F_decodeTextUnmarshaler obj.Addr +) + +func init() { + _F_decodeJsonUnmarshaler = jit.Func(decodeJsonUnmarshaler) + _F_decodeTextUnmarshaler = jit.Func(decodeTextUnmarshaler) +} + +func (self *_Assembler) mapaccess_ptr(t reflect.Type) { + if rt.MapType(rt.UnpackType(t)).IndirectElem() { + self.vfollow(t.Elem()) + } +} + +func (self *_Assembler) mapassign_std(t reflect.Type, v obj.Addr) { + self.Emit("LEAQ", v, _AX) // LEAQ ${v}, AX + self.mapassign_call_from_AX(t, _F_mapassign) // MAPASSIGN ${t}, mapassign +} + +func (self *_Assembler) mapassign_str_fast(t reflect.Type, p obj.Addr, n obj.Addr) { + self.Emit("MOVQ", jit.Type(t), _AX) // MOVQ ${t}, AX + self.Emit("MOVQ", _VP, _BX) // MOVQ VP, BX + self.Emit("MOVQ", p, _CX) // MOVQ ${p}, CX + self.Emit("MOVQ", n, _DI) // MOVQ ${n}, DI + self.call_go(_F_mapassign_faststr) // CALL_GO ${fn} + self.Emit("MOVQ", _AX, _VP) // MOVQ AX, VP + self.mapaccess_ptr(t) +} + +func (self *_Assembler) mapassign_call_from_AX(t reflect.Type, fn obj.Addr) { + self.Emit("MOVQ", _AX, _CX) + self.Emit("MOVQ", jit.Type(t), _AX) // MOVQ ${t}, AX + self.Emit("MOVQ", _VP, _BX) // MOVQ VP, _BX + self.call_go(fn) // CALL_GO ${fn} + self.Emit("MOVQ", _AX, _VP) // MOVQ AX, VP +} + +func (self *_Assembler) mapassign_fastx(t reflect.Type, fn obj.Addr) { + self.mapassign_call_from_AX(t, fn) + self.mapaccess_ptr(t) +} + +func (self *_Assembler) mapassign_utext(t reflect.Type, addressable bool) { + pv := false + vk := t.Key() + tk := t.Key() + + /* deref pointer if needed */ + if vk.Kind() == reflect.Ptr { + pv = true + vk = vk.Elem() + } + + /* addressable value with pointer receiver */ + if addressable { + pv = false + tk = reflect.PtrTo(tk) + } + + /* allocate the key, and call the unmarshaler */ + self.valloc(vk, _BX) // VALLOC ${vk}, BX + // must spill vk pointer since next call_go may invoke GC + self.Emit("MOVQ" , _BX, _ARG_vk) + self.Emit("MOVQ" , jit.Type(tk), _AX) // MOVQ ${tk}, AX + self.Emit("MOVQ" , _ARG_sv_p, _CX) // MOVQ sv.p, CX + self.Emit("MOVQ" , _ARG_sv_n, _DI) // MOVQ sv.n, DI + self.call_go(_F_decodeTextUnmarshaler) // CALL_GO decodeTextUnmarshaler + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error + self.Emit("MOVQ" , _ARG_vk, _AX) // MOVQ VAR.vk, AX + self.Emit("MOVQ", jit.Imm(0), _ARG_vk) + + /* select the correct assignment function */ + if !pv { + self.mapassign_call_from_AX(t, _F_mapassign) + } else { + self.mapassign_fastx(t, _F_mapassign_fast64ptr) + } +} + +/** External Unmarshaler Routines **/ + +var ( + _F_skip_one = jit.Imm(int64(native.S_skip_one)) + _F_skip_array = jit.Imm(int64(native.S_skip_array)) + _F_skip_object = jit.Imm(int64(native.S_skip_object)) + _F_skip_number = jit.Imm(int64(native.S_skip_number)) +) + +func (self *_Assembler) unmarshal_json(t reflect.Type, deref bool) { + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v + self.slice_from_r(_AX, 0) // SLICE_R AX, $0 + self.Emit("MOVQ" , _DI, _ARG_sv_p) // MOVQ DI, sv.p + self.Emit("MOVQ" , _SI, _ARG_sv_n) // MOVQ SI, sv.n + self.unmarshal_func(t, _F_decodeJsonUnmarshaler, deref) // UNMARSHAL json, ${t}, ${deref} +} + +func (self *_Assembler) unmarshal_text(t reflect.Type, deref bool) { + self.parse_string() // PARSE STRING + self.unquote_once(_ARG_sv_p, _ARG_sv_n, true, true) // UNQUOTE once, sv.p, sv.n + self.unmarshal_func(t, _F_decodeTextUnmarshaler, deref) // UNMARSHAL text, ${t}, ${deref} +} + +func (self *_Assembler) unmarshal_func(t reflect.Type, fn obj.Addr, deref bool) { + pt := t + vk := t.Kind() + + /* allocate the field if needed */ + if deref && vk == reflect.Ptr { + self.Emit("MOVQ" , _VP, _BX) // MOVQ VP, BX + self.Emit("MOVQ" , jit.Ptr(_BX, 0), _BX) // MOVQ (BX), BX + self.Emit("TESTQ", _BX, _BX) // TESTQ BX, BX + self.Sjmp("JNZ" , "_deref_{n}") // JNZ _deref_{n} + self.valloc(t.Elem(), _BX) // VALLOC ${t.Elem()}, BX + self.WriteRecNotAX(3, _BX, jit.Ptr(_VP, 0), false, false) // MOVQ BX, (VP) + self.Link("_deref_{n}") // _deref_{n}: + } else { + /* set value pointer */ + self.Emit("MOVQ", _VP, _BX) // MOVQ (VP), BX + } + + /* set value type */ + self.Emit("MOVQ", jit.Type(pt), _AX) // MOVQ ${pt}, AX + + /* set the source string and call the unmarshaler */ + self.Emit("MOVQ" , _ARG_sv_p, _CX) // MOVQ sv.p, CX + self.Emit("MOVQ" , _ARG_sv_n, _DI) // MOVQ sv.n, DI + self.call_go(fn) // CALL_GO ${fn} + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error +} + +/** Dynamic Decoding Routine **/ + +var ( + _F_decodeTypedPointer obj.Addr +) + +func init() { + _F_decodeTypedPointer = jit.Func(decodeTypedPointer) +} + +func (self *_Assembler) decode_dynamic(vt obj.Addr, vp obj.Addr) { + self.Emit("MOVQ" , vp, _SI) // MOVQ ${vp}, SI + self.Emit("MOVQ" , vt, _DI) // MOVQ ${vt}, DI + self.Emit("MOVQ", _ARG_sp, _AX) // MOVQ sp, AX + self.Emit("MOVQ", _ARG_sl, _BX) // MOVQ sp, BX + self.Emit("MOVQ" , _IC, _CX) // MOVQ IC, CX + self.Emit("MOVQ" , _ST, _R8) // MOVQ ST, R8 + self.Emit("MOVQ" , _ARG_fv, _R9) // MOVQ fv, R9 + self.save(_REG_rt...) + self.Emit("MOVQ", _F_decodeTypedPointer, _IL) // MOVQ ${fn}, R11 + self.Rjmp("CALL", _IL) // CALL R11 + self.load(_REG_rt...) + self.Emit("MOVQ" , _AX, _IC) // MOVQ AX, IC + self.Emit("MOVQ" , _BX, _ET) // MOVQ BX, ET + self.Emit("MOVQ" , _CX, _EP) // MOVQ CX, EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error +} + +/** OpCode Assembler Functions **/ + +var ( + _F_memequal = jit.Func(memequal) + _F_memmove = jit.Func(memmove) + _F_growslice = jit.Func(growslice) + _F_makeslice = jit.Func(makeslice) + _F_makemap_small = jit.Func(makemap_small) + _F_mapassign_fast64 = jit.Func(mapassign_fast64) +) + +var ( + _F_lspace = jit.Imm(int64(native.S_lspace)) + _F_strhash = jit.Imm(int64(caching.S_strhash)) +) + +var ( + _F_b64decode = jit.Imm(int64(_subr__b64decode)) + _F_decodeValue = jit.Imm(int64(_subr_decode_value)) +) + +var ( + _F_FieldMap_GetCaseInsensitive obj.Addr +) + +const ( + _MODE_AVX2 = 1 << 2 +) + +const ( + _Fe_ID = int64(unsafe.Offsetof(caching.FieldEntry{}.ID)) + _Fe_Name = int64(unsafe.Offsetof(caching.FieldEntry{}.Name)) + _Fe_Hash = int64(unsafe.Offsetof(caching.FieldEntry{}.Hash)) +) + +const ( + _Vk_Ptr = int64(reflect.Ptr) + _Gt_KindFlags = int64(unsafe.Offsetof(rt.GoType{}.KindFlags)) +) + +func init() { + _F_FieldMap_GetCaseInsensitive = jit.Func((*caching.FieldMap).GetCaseInsensitive) +} + +func (self *_Assembler) _asm_OP_any(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_VP, 8), _CX) // MOVQ 8(VP), CX + self.Emit("TESTQ" , _CX, _CX) // TESTQ CX, CX + self.Sjmp("JZ" , "_decode_{n}") // JZ _decode_{n} + self.Emit("CMPQ" , _CX, _VP) // CMPQ CX, VP + self.Sjmp("JE" , "_decode_{n}") // JE _decode_{n} + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _AX) // MOVQ (VP), AX + self.Emit("MOVBLZX", jit.Ptr(_AX, _Gt_KindFlags), _DX) // MOVBLZX _Gt_KindFlags(AX), DX + self.Emit("ANDL" , jit.Imm(rt.F_kind_mask), _DX) // ANDL ${F_kind_mask}, DX + self.Emit("CMPL" , _DX, jit.Imm(_Vk_Ptr)) // CMPL DX, ${reflect.Ptr} + self.Sjmp("JNE" , "_decode_{n}") // JNE _decode_{n} + self.Emit("LEAQ" , jit.Ptr(_VP, 8), _DI) // LEAQ 8(VP), DI + self.decode_dynamic(_AX, _DI) // DECODE AX, DI + self.Sjmp("JMP" , "_decode_end_{n}") // JMP _decode_end_{n} + self.Link("_decode_{n}") // _decode_{n}: + self.Emit("MOVQ" , _ARG_fv, _DF) // MOVQ fv, DF + self.Emit("MOVQ" , _ST, jit.Ptr(_SP, 0)) // MOVQ _ST, (SP) + self.call(_F_decodeValue) // CALL decodeValue + self.Emit("MOVQ" , jit.Imm(0), jit.Ptr(_SP, 0)) // MOVQ _ST, (SP) + self.Emit("TESTQ" , _EP, _EP) // TESTQ EP, EP + self.Sjmp("JNZ" , _LB_parsing_error) // JNZ _parsing_error + self.Link("_decode_end_{n}") // _decode_end_{n}: +} + +func (self *_Assembler) _asm_OP_dyn(p *_Instr) { + self.Emit("MOVQ" , jit.Type(p.vt()), _ET) // MOVQ ${p.vt()}, ET + self.Emit("CMPQ" , jit.Ptr(_VP, 8), jit.Imm(0)) // CMPQ 8(VP), $0 + self.Sjmp("JE" , _LB_type_error) // JE _type_error + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _CX) // MOVQ (VP), CX + self.Emit("MOVQ" , jit.Ptr(_CX, 8), _CX) // MOVQ 8(CX), CX + self.Emit("MOVBLZX", jit.Ptr(_CX, _Gt_KindFlags), _DX) // MOVBLZX _Gt_KindFlags(CX), DX + self.Emit("ANDL" , jit.Imm(rt.F_kind_mask), _DX) // ANDL ${F_kind_mask}, DX + self.Emit("CMPL" , _DX, jit.Imm(_Vk_Ptr)) // CMPL DX, ${reflect.Ptr} + self.Sjmp("JNE" , _LB_type_error) // JNE _type_error + self.Emit("LEAQ" , jit.Ptr(_VP, 8), _DI) // LEAQ 8(VP), DI + self.decode_dynamic(_CX, _DI) // DECODE CX, DI + self.Link("_decode_end_{n}") // _decode_end_{n}: +} + +func (self *_Assembler) _asm_OP_str(_ *_Instr) { + self.parse_string() // PARSE STRING + self.unquote_once(jit.Ptr(_VP, 0), jit.Ptr(_VP, 8), false, true) // UNQUOTE once, (VP), 8(VP) +} + +func (self *_Assembler) _asm_OP_bin(_ *_Instr) { + self.parse_string() // PARSE STRING + self.slice_from(_VAR_st_Iv, -1) // SLICE st.Iv, $-1 + self.Emit("MOVQ" , _DI, jit.Ptr(_VP, 0)) // MOVQ DI, (VP) + self.Emit("MOVQ" , _SI, jit.Ptr(_VP, 8)) // MOVQ SI, 8(VP) + self.Emit("SHRQ" , jit.Imm(2), _SI) // SHRQ $2, SI + self.Emit("LEAQ" , jit.Sib(_SI, _SI, 2, 0), _SI) // LEAQ (SI)(SI*2), SI + self.Emit("MOVQ" , _SI, jit.Ptr(_VP, 16)) // MOVQ SI, 16(VP) + self.malloc_AX(_SI, _SI) // MALLOC SI, SI + + // TODO: due to base64x's bug, only use AVX mode now + self.Emit("MOVL", jit.Imm(_MODE_JSON), _CX) // MOVL $_MODE_JSON, CX + + /* call the decoder */ + self.Emit("XORL" , _DX, _DX) // XORL DX, DX + self.Emit("MOVQ" , _VP, _DI) // MOVQ VP, DI + + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _R8) // MOVQ SI, (VP) + self.WriteRecNotAX(4, _SI, jit.Ptr(_VP, 0), true, false) // XCHGQ SI, (VP) + self.Emit("MOVQ" , _R8, _SI) + + self.Emit("XCHGQ", _DX, jit.Ptr(_VP, 8)) // XCHGQ DX, 8(VP) + self.call_c(_F_b64decode) // CALL b64decode + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_base64_error) // JS _base64_error + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) +} + +func (self *_Assembler) _asm_OP_bool(_ *_Instr) { + self.Emit("LEAQ", jit.Ptr(_IC, 4), _AX) // LEAQ 4(IC), AX + self.Emit("CMPQ", _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , _LB_eof_error) // JA _eof_error + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm('f')) // CMPB (IP)(IC), $'f' + self.Sjmp("JE" , "_false_{n}") // JE _false_{n} + self.Emit("MOVL", jit.Imm(_IM_true), _CX) // MOVL $"true", CX + self.Emit("CMPL", _CX, jit.Sib(_IP, _IC, 1, 0)) // CMPL CX, (IP)(IC) + self.Sjmp("JE" , "_bool_true_{n}") + // try to skip the value + self.Emit("MOVQ", _IC, _VAR_ic) + self.Emit("MOVQ", _T_bool, _ET) + self.Emit("MOVQ", _ET, _VAR_et) + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_end_{n}", 4) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_one) + + self.Link("_bool_true_{n}") + self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC + self.Emit("MOVB", jit.Imm(1), jit.Ptr(_VP, 0)) // MOVB $1, (VP) + self.Sjmp("JMP" , "_end_{n}") // JMP _end_{n} + self.Link("_false_{n}") // _false_{n}: + self.Emit("ADDQ", jit.Imm(1), _AX) // ADDQ $1, AX + self.Emit("ADDQ", jit.Imm(1), _IC) // ADDQ $1, IC + self.Emit("CMPQ", _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , _LB_eof_error) // JA _eof_error + self.Emit("MOVL", jit.Imm(_IM_alse), _CX) // MOVL $"alse", CX + self.Emit("CMPL", _CX, jit.Sib(_IP, _IC, 1, 0)) // CMPL CX, (IP)(IC) + self.Sjmp("JNE" , _LB_im_error) // JNE _im_error + self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("MOVB", _AX, jit.Ptr(_VP, 0)) // MOVB AX, (VP) + self.Link("_end_{n}") // _end_{n}: +} + +func (self *_Assembler) _asm_OP_num(_ *_Instr) { + self.Emit("MOVQ", jit.Imm(0), _VAR_fl) + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm('"')) + self.Emit("MOVQ", _IC, _BX) + self.Sjmp("JNE", "_skip_number_{n}") + self.Emit("MOVQ", jit.Imm(1), _VAR_fl) + self.Emit("ADDQ", jit.Imm(1), _IC) + self.Link("_skip_number_{n}") + + /* call skip_number */ + self.Emit("LEAQ", _ARG_s, _DI) // LEAQ s<>+0(FP), DI + self.Emit("MOVQ", _IC, _ARG_ic) // MOVQ IC, ic<>+16(FP) + self.Emit("LEAQ", _ARG_ic, _SI) // LEAQ ic<>+16(FP), SI + self.callc(_F_skip_number) // CALL _F_skip_number + self.Emit("MOVQ", _ARG_ic, _IC) // MOVQ ic<>+16(FP), IC + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNS" , "_num_next_{n}") + + /* call skip one */ + self.Emit("MOVQ", _BX, _VAR_ic) + self.Emit("MOVQ", _T_number, _ET) + self.Emit("MOVQ", _ET, _VAR_et) + self.Byte(0x4c, 0x8d, 0x0d) + self.Sref("_num_end_{n}", 4) + self.Emit("MOVQ", _R9, _VAR_pc) + self.Sjmp("JMP" , _LB_skip_one) + + /* assgin string */ + self.Link("_num_next_{n}") + self.slice_from_r(_AX, 0) + self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv) + self.Sjmp("JNC", "_num_write_{n}") + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ (PC), R9 + self.Sref("_num_write_{n}", 4) + self.Sjmp("JMP", "_copy_string") + self.Link("_num_write_{n}") + self.Emit("MOVQ", _SI, jit.Ptr(_VP, 8)) // MOVQ SI, 8(VP) + self.WriteRecNotAX(13, _DI, jit.Ptr(_VP, 0), false, false) + self.Emit("CMPQ", _VAR_fl, jit.Imm(1)) + self.Sjmp("JNE", "_num_end_{n}") + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm('"')) + self.Sjmp("JNE", _LB_char_0_error) + self.Emit("ADDQ", jit.Imm(1), _IC) + self.Link("_num_end_{n}") +} + +func (self *_Assembler) _asm_OP_i8(_ *_Instr) { + var pin = "_i8_end_{n}" + self.parse_signed(int8Type, pin, -1) // PARSE int8 + self.range_signed_CX(_I_int8, _T_int8, math.MinInt8, math.MaxInt8) // RANGE int8 + self.Emit("MOVB", _CX, jit.Ptr(_VP, 0)) // MOVB CX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_i16(_ *_Instr) { + var pin = "_i16_end_{n}" + self.parse_signed(int16Type, pin, -1) // PARSE int16 + self.range_signed_CX(_I_int16, _T_int16, math.MinInt16, math.MaxInt16) // RANGE int16 + self.Emit("MOVW", _CX, jit.Ptr(_VP, 0)) // MOVW CX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_i32(_ *_Instr) { + var pin = "_i32_end_{n}" + self.parse_signed(int32Type, pin, -1) // PARSE int32 + self.range_signed_CX(_I_int32, _T_int32, math.MinInt32, math.MaxInt32) // RANGE int32 + self.Emit("MOVL", _CX, jit.Ptr(_VP, 0)) // MOVL CX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_i64(_ *_Instr) { + var pin = "_i64_end_{n}" + self.parse_signed(int64Type, pin, -1) // PARSE int64 + self.Emit("MOVQ", _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.Emit("MOVQ", _AX, jit.Ptr(_VP, 0)) // MOVQ AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_u8(_ *_Instr) { + var pin = "_u8_end_{n}" + self.parse_unsigned(uint8Type, pin, -1) // PARSE uint8 + self.range_unsigned_CX(_I_uint8, _T_uint8, math.MaxUint8) // RANGE uint8 + self.Emit("MOVB", _CX, jit.Ptr(_VP, 0)) // MOVB CX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_u16(_ *_Instr) { + var pin = "_u16_end_{n}" + self.parse_unsigned(uint16Type, pin, -1) // PARSE uint16 + self.range_unsigned_CX(_I_uint16, _T_uint16, math.MaxUint16) // RANGE uint16 + self.Emit("MOVW", _CX, jit.Ptr(_VP, 0)) // MOVW CX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_u32(_ *_Instr) { + var pin = "_u32_end_{n}" + self.parse_unsigned(uint32Type, pin, -1) // PARSE uint32 + self.range_unsigned_CX(_I_uint32, _T_uint32, math.MaxUint32) // RANGE uint32 + self.Emit("MOVL", _CX, jit.Ptr(_VP, 0)) // MOVL CX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_u64(_ *_Instr) { + var pin = "_u64_end_{n}" + self.parse_unsigned(uint64Type, pin, -1) // PARSE uint64 + self.Emit("MOVQ", _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.Emit("MOVQ", _AX, jit.Ptr(_VP, 0)) // MOVQ AX, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_f32(_ *_Instr) { + var pin = "_f32_end_{n}" + self.parse_number(float32Type, pin, -1) // PARSE NUMBER + self.range_single_X0() // RANGE float32 + self.Emit("MOVSS", _X0, jit.Ptr(_VP, 0)) // MOVSS X0, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_f64(_ *_Instr) { + var pin = "_f64_end_{n}" + self.parse_number(float64Type, pin, -1) // PARSE NUMBER + self.Emit("MOVSD", _VAR_st_Dv, _X0) // MOVSD st.Dv, X0 + self.Emit("MOVSD", _X0, jit.Ptr(_VP, 0)) // MOVSD X0, (VP) + self.Link(pin) +} + +func (self *_Assembler) _asm_OP_unquote(_ *_Instr) { + self.check_eof(2) + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm('\\')) // CMPB (IP)(IC), $'\\' + self.Sjmp("JNE" , _LB_char_0_error) // JNE _char_0_error + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 1), jit.Imm('"')) // CMPB 1(IP)(IC), $'"' + self.Sjmp("JNE" , _LB_char_1_error) // JNE _char_1_error + self.Emit("ADDQ", jit.Imm(2), _IC) // ADDQ $2, IC + self.parse_string() // PARSE STRING + self.unquote_twice(jit.Ptr(_VP, 0), jit.Ptr(_VP, 8), false) // UNQUOTE twice, (VP), 8(VP) +} + +func (self *_Assembler) _asm_OP_nil_1(_ *_Instr) { + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("MOVQ", _AX, jit.Ptr(_VP, 0)) // MOVQ AX, (VP) +} + +func (self *_Assembler) _asm_OP_nil_2(_ *_Instr) { + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_VP, 0)) // MOVOU X0, (VP) +} + +func (self *_Assembler) _asm_OP_nil_3(_ *_Instr) { + self.Emit("XORL" , _AX, _AX) // XORL AX, AX + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_VP, 0)) // MOVOU X0, (VP) + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 16)) // MOVOU AX, 16(VP) +} + +func (self *_Assembler) _asm_OP_deref(p *_Instr) { + self.vfollow(p.vt()) +} + +func (self *_Assembler) _asm_OP_index(p *_Instr) { + self.Emit("MOVQ", jit.Imm(p.i64()), _AX) // MOVQ ${p.vi()}, AX + self.Emit("ADDQ", _AX, _VP) // ADDQ _AX, _VP +} + +func (self *_Assembler) _asm_OP_is_null(p *_Instr) { + self.Emit("LEAQ" , jit.Ptr(_IC, 4), _AX) // LEAQ 4(IC), AX + self.Emit("CMPQ" , _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , "_not_null_{n}") // JA _not_null_{n} + self.Emit("CMPL" , jit.Sib(_IP, _IC, 1, 0), jit.Imm(_IM_null)) // CMPL (IP)(IC), $"null" + self.Emit("CMOVQEQ", _AX, _IC) // CMOVQEQ AX, IC + self.Xjmp("JE" , p.vi()) // JE {p.vi()} + self.Link("_not_null_{n}") // _not_null_{n}: +} + +func (self *_Assembler) _asm_OP_is_null_quote(p *_Instr) { + self.Emit("LEAQ" , jit.Ptr(_IC, 5), _AX) // LEAQ 4(IC), AX + self.Emit("CMPQ" , _AX, _IL) // CMPQ AX, IL + self.Sjmp("JA" , "_not_null_quote_{n}") // JA _not_null_quote_{n} + self.Emit("CMPL" , jit.Sib(_IP, _IC, 1, 0), jit.Imm(_IM_null)) // CMPL (IP)(IC), $"null" + self.Sjmp("JNE" , "_not_null_quote_{n}") // JNE _not_null_quote_{n} + self.Emit("CMPB" , jit.Sib(_IP, _IC, 1, 4), jit.Imm('"')) // CMPB 4(IP)(IC), $'"' + self.Emit("CMOVQEQ", _AX, _IC) // CMOVQEQ AX, IC + self.Xjmp("JE" , p.vi()) // JE {p.vi()} + self.Link("_not_null_quote_{n}") // _not_null_quote_{n}: +} + +func (self *_Assembler) _asm_OP_map_init(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _AX) // MOVQ (VP), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNZ" , "_end_{n}") // JNZ _end_{n} + self.call_go(_F_makemap_small) // CALL_GO makemap_small + self.WritePtrAX(6, jit.Ptr(_VP, 0), false) // MOVQ AX, (VP) + self.Link("_end_{n}") // _end_{n}: + self.Emit("MOVQ" , _AX, _VP) // MOVQ AX, VP +} + +func (self *_Assembler) _asm_OP_map_key_i8(p *_Instr) { + self.parse_signed(int8Type, "", p.vi()) // PARSE int8 + self.range_signed_CX(_I_int8, _T_int8, math.MinInt8, math.MaxInt8) // RANGE int8 + self.mapassign_std(p.vt(), _VAR_st_Iv) // MAPASSIGN int8, mapassign, st.Iv +} + +func (self *_Assembler) _asm_OP_map_key_i16(p *_Instr) { + self.parse_signed(int16Type, "", p.vi()) // PARSE int16 + self.range_signed_CX(_I_int16, _T_int16, math.MinInt16, math.MaxInt16) // RANGE int16 + self.mapassign_std(p.vt(), _VAR_st_Iv) // MAPASSIGN int16, mapassign, st.Iv +} + +func (self *_Assembler) _asm_OP_map_key_i32(p *_Instr) { + self.parse_signed(int32Type, "", p.vi()) // PARSE int32 + self.range_signed_CX(_I_int32, _T_int32, math.MinInt32, math.MaxInt32) // RANGE int32 + if vt := p.vt(); !mapfast(vt) { + self.mapassign_std(vt, _VAR_st_Iv) // MAPASSIGN int32, mapassign, st.Iv + } else { + self.Emit("MOVQ", _CX, _AX) // MOVQ CX, AX + self.mapassign_fastx(vt, _F_mapassign_fast32) // MAPASSIGN int32, mapassign_fast32 + } +} + +func (self *_Assembler) _asm_OP_map_key_i64(p *_Instr) { + self.parse_signed(int64Type, "", p.vi()) // PARSE int64 + if vt := p.vt(); !mapfast(vt) { + self.mapassign_std(vt, _VAR_st_Iv) // MAPASSIGN int64, mapassign, st.Iv + } else { + self.Emit("MOVQ", _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.mapassign_fastx(vt, _F_mapassign_fast64) // MAPASSIGN int64, mapassign_fast64 + } +} + +func (self *_Assembler) _asm_OP_map_key_u8(p *_Instr) { + self.parse_unsigned(uint8Type, "", p.vi()) // PARSE uint8 + self.range_unsigned_CX(_I_uint8, _T_uint8, math.MaxUint8) // RANGE uint8 + self.mapassign_std(p.vt(), _VAR_st_Iv) // MAPASSIGN uint8, vt.Iv +} + +func (self *_Assembler) _asm_OP_map_key_u16(p *_Instr) { + self.parse_unsigned(uint16Type, "", p.vi()) // PARSE uint16 + self.range_unsigned_CX(_I_uint16, _T_uint16, math.MaxUint16) // RANGE uint16 + self.mapassign_std(p.vt(), _VAR_st_Iv) // MAPASSIGN uint16, vt.Iv +} + +func (self *_Assembler) _asm_OP_map_key_u32(p *_Instr) { + self.parse_unsigned(uint32Type, "", p.vi()) // PARSE uint32 + self.range_unsigned_CX(_I_uint32, _T_uint32, math.MaxUint32) // RANGE uint32 + if vt := p.vt(); !mapfast(vt) { + self.mapassign_std(vt, _VAR_st_Iv) // MAPASSIGN uint32, vt.Iv + } else { + self.Emit("MOVQ", _CX, _AX) // MOVQ CX, AX + self.mapassign_fastx(vt, _F_mapassign_fast32) // MAPASSIGN uint32, mapassign_fast32 + } +} + +func (self *_Assembler) _asm_OP_map_key_u64(p *_Instr) { + self.parse_unsigned(uint64Type, "", p.vi()) // PARSE uint64 + if vt := p.vt(); !mapfast(vt) { + self.mapassign_std(vt, _VAR_st_Iv) // MAPASSIGN uint64, vt.Iv + } else { + self.Emit("MOVQ", _VAR_st_Iv, _AX) // MOVQ st.Iv, AX + self.mapassign_fastx(vt, _F_mapassign_fast64) // MAPASSIGN uint64, mapassign_fast64 + } +} + +func (self *_Assembler) _asm_OP_map_key_f32(p *_Instr) { + self.parse_number(float32Type, "", p.vi()) // PARSE NUMBER + self.range_single_X0() // RANGE float32 + self.Emit("MOVSS", _X0, _VAR_st_Dv) // MOVSS X0, st.Dv + self.mapassign_std(p.vt(), _VAR_st_Dv) // MAPASSIGN ${p.vt()}, mapassign, st.Dv +} + +func (self *_Assembler) _asm_OP_map_key_f64(p *_Instr) { + self.parse_number(float64Type, "", p.vi()) // PARSE NUMBER + self.mapassign_std(p.vt(), _VAR_st_Dv) // MAPASSIGN ${p.vt()}, mapassign, st.Dv +} + +func (self *_Assembler) _asm_OP_map_key_str(p *_Instr) { + self.parse_string() // PARSE STRING + self.unquote_once(_ARG_sv_p, _ARG_sv_n, true, true) // UNQUOTE once, sv.p, sv.n + if vt := p.vt(); !mapfast(vt) { + self.valloc(vt.Key(), _DI) + self.Emit("MOVOU", _ARG_sv, _X0) + self.Emit("MOVOU", _X0, jit.Ptr(_DI, 0)) + self.mapassign_std(vt, jit.Ptr(_DI, 0)) // MAPASSIGN string, DI, SI + } else { + self.mapassign_str_fast(vt, _ARG_sv_p, _ARG_sv_n) // MAPASSIGN string, DI, SI + } +} + +func (self *_Assembler) _asm_OP_map_key_utext(p *_Instr) { + self.parse_string() // PARSE STRING + self.unquote_once(_ARG_sv_p, _ARG_sv_n, true, true) // UNQUOTE once, sv.p, sv.n + self.mapassign_utext(p.vt(), false) // MAPASSIGN utext, ${p.vt()}, false +} + +func (self *_Assembler) _asm_OP_map_key_utext_p(p *_Instr) { + self.parse_string() // PARSE STRING + self.unquote_once(_ARG_sv_p, _ARG_sv_n, true, true) // UNQUOTE once, sv.p, sv.n + self.mapassign_utext(p.vt(), true) // MAPASSIGN utext, ${p.vt()}, true +} + +func (self *_Assembler) _asm_OP_array_skip(_ *_Instr) { + self.call_sf(_F_skip_array) // CALL_SF skip_array + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v +} + +func (self *_Assembler) _asm_OP_array_clear(p *_Instr) { + self.mem_clear_rem(p.i64(), true) +} + +func (self *_Assembler) _asm_OP_array_clear_p(p *_Instr) { + self.mem_clear_rem(p.i64(), false) +} + +func (self *_Assembler) _asm_OP_slice_init(p *_Instr) { + self.Emit("XORL" , _AX, _AX) // XORL AX, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) + self.Emit("MOVQ" , jit.Ptr(_VP, 16), _BX) // MOVQ 16(VP), BX + self.Emit("TESTQ", _BX, _BX) // TESTQ BX, BX + self.Sjmp("JNZ" , "_done_{n}") // JNZ _done_{n} + self.Emit("MOVQ" , jit.Imm(_MinSlice), _CX) // MOVQ ${_MinSlice}, CX + self.Emit("MOVQ" , _CX, jit.Ptr(_VP, 16)) // MOVQ CX, 16(VP) + self.Emit("MOVQ" , jit.Type(p.vt()), _AX) // MOVQ ${p.vt()}, DX + self.call_go(_F_makeslice) // CALL_GO makeslice + self.WritePtrAX(7, jit.Ptr(_VP, 0), false) // MOVQ AX, (VP) + self.Emit("XORL" , _AX, _AX) // XORL AX, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) + self.Link("_done_{n}") // _done_{n} +} + +func (self *_Assembler) _asm_OP_slice_append(p *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_VP, 8), _AX) // MOVQ 8(VP), AX + self.Emit("CMPQ" , _AX, jit.Ptr(_VP, 16)) // CMPQ AX, 16(VP) + self.Sjmp("JB" , "_index_{n}") // JB _index_{n} + self.Emit("MOVQ" , _AX, _SI) // MOVQ AX, SI + self.Emit("SHLQ" , jit.Imm(1), _SI) // SHLQ $1, SI + self.Emit("MOVQ" , jit.Type(p.vt()), _AX) // MOVQ ${p.vt()}, AX + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _BX) // MOVQ (VP), BX + self.Emit("MOVQ" , jit.Ptr(_VP, 8), _CX) // MOVQ 8(VP), CX + self.Emit("MOVQ" , jit.Ptr(_VP, 16), _DI) // MOVQ 16(VP), DI + self.call_go(_F_growslice) // CALL_GO growslice + self.WritePtrAX(8, jit.Ptr(_VP, 0), false) // MOVQ AX, (VP) + self.Emit("MOVQ" , _BX, jit.Ptr(_VP, 8)) // MOVQ BX, 8(VP) + self.Emit("MOVQ" , _CX, jit.Ptr(_VP, 16)) // MOVQ CX, 16(VP) + self.Emit("MOVQ" , _BX, _AX) // MOVQ BX, AX + self.Link("_index_{n}") // _index_{n}: + self.Emit("ADDQ" , jit.Imm(1), jit.Ptr(_VP, 8)) // ADDQ $1, 8(VP) + self.Emit("MOVQ" , jit.Ptr(_VP, 0), _VP) // MOVQ (VP), VP + self.Emit("MOVQ" , jit.Imm(int64(p.vlen())), _CX) // MOVQ ${p.vlen()}, CX + self.From("MULQ" , _CX) // MULQ CX + self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP +} + +func (self *_Assembler) _asm_OP_object_skip(_ *_Instr) { + self.call_sf(_F_skip_object) // CALL_SF skip_object + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v +} + +func (self *_Assembler) _asm_OP_object_next(_ *_Instr) { + self.call_sf(_F_skip_one) // CALL_SF skip_one + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parse_error_v +} + +func (self *_Assembler) _asm_OP_struct_field(p *_Instr) { + assert_eq(caching.FieldEntrySize, 32, "invalid field entry size") + self.Emit("MOVQ" , jit.Imm(-1), _AX) // MOVQ $-1, AX + self.Emit("MOVQ" , _AX, _VAR_sr) // MOVQ AX, sr + self.parse_string() // PARSE STRING + self.unquote_once(_ARG_sv_p, _ARG_sv_n, true, false) // UNQUOTE once, sv.p, sv.n + self.Emit("LEAQ" , _ARG_sv, _AX) // LEAQ sv, AX + self.Emit("XORL" , _BX, _BX) // XORL BX, BX + self.call_go(_F_strhash) // CALL_GO strhash + self.Emit("MOVQ" , _AX, _R9) // MOVQ AX, R9 + self.Emit("MOVQ" , jit.Imm(freezeFields(p.vf())), _CX) // MOVQ ${p.vf()}, CX + self.Emit("MOVQ" , jit.Ptr(_CX, caching.FieldMap_b), _SI) // MOVQ FieldMap.b(CX), SI + self.Emit("MOVQ" , jit.Ptr(_CX, caching.FieldMap_N), _CX) // MOVQ FieldMap.N(CX), CX + self.Emit("TESTQ", _CX, _CX) // TESTQ CX, CX + self.Sjmp("JZ" , "_try_lowercase_{n}") // JZ _try_lowercase_{n} + self.Link("_loop_{n}") // _loop_{n}: + self.Emit("XORL" , _DX, _DX) // XORL DX, DX + self.From("DIVQ" , _CX) // DIVQ CX + self.Emit("LEAQ" , jit.Ptr(_DX, 1), _AX) // LEAQ 1(DX), AX + self.Emit("SHLQ" , jit.Imm(5), _DX) // SHLQ $5, DX + self.Emit("LEAQ" , jit.Sib(_SI, _DX, 1, 0), _DI) // LEAQ (SI)(DX), DI + self.Emit("MOVQ" , jit.Ptr(_DI, _Fe_Hash), _R8) // MOVQ FieldEntry.Hash(DI), R8 + self.Emit("TESTQ", _R8, _R8) // TESTQ R8, R8 + self.Sjmp("JZ" , "_try_lowercase_{n}") // JZ _try_lowercase_{n} + self.Emit("CMPQ" , _R8, _R9) // CMPQ R8, R9 + self.Sjmp("JNE" , "_loop_{n}") // JNE _loop_{n} + self.Emit("MOVQ" , jit.Ptr(_DI, _Fe_Name + 8), _DX) // MOVQ FieldEntry.Name+8(DI), DX + self.Emit("CMPQ" , _DX, _ARG_sv_n) // CMPQ DX, sv.n + self.Sjmp("JNE" , "_loop_{n}") // JNE _loop_{n} + self.Emit("MOVQ" , jit.Ptr(_DI, _Fe_ID), _R8) // MOVQ FieldEntry.ID(DI), R8 + self.Emit("MOVQ" , _AX, _VAR_ss_AX) // MOVQ AX, ss.AX + self.Emit("MOVQ" , _CX, _VAR_ss_CX) // MOVQ CX, ss.CX + self.Emit("MOVQ" , _SI, _VAR_ss_SI) // MOVQ SI, ss.SI + self.Emit("MOVQ" , _R8, _VAR_ss_R8) // MOVQ R8, ss.R8 + self.Emit("MOVQ" , _R9, _VAR_ss_R9) // MOVQ R9, ss.R9 + self.Emit("MOVQ" , _ARG_sv_p, _AX) // MOVQ _VAR_sv_p, AX + self.Emit("MOVQ" , jit.Ptr(_DI, _Fe_Name), _CX) // MOVQ FieldEntry.Name(DI), CX + self.Emit("MOVQ" , _CX, _BX) // MOVQ CX, 8(SP) + self.Emit("MOVQ" , _DX, _CX) // MOVQ DX, 16(SP) + self.call_go(_F_memequal) // CALL_GO memequal + self.Emit("MOVB" , _AX, _DX) // MOVB 24(SP), DX + self.Emit("MOVQ" , _VAR_ss_AX, _AX) // MOVQ ss.AX, AX + self.Emit("MOVQ" , _VAR_ss_CX, _CX) // MOVQ ss.CX, CX + self.Emit("MOVQ" , _VAR_ss_SI, _SI) // MOVQ ss.SI, SI + self.Emit("MOVQ" , _VAR_ss_R9, _R9) // MOVQ ss.R9, R9 + self.Emit("TESTB", _DX, _DX) // TESTB DX, DX + self.Sjmp("JZ" , "_loop_{n}") // JZ _loop_{n} + self.Emit("MOVQ" , _VAR_ss_R8, _R8) // MOVQ ss.R8, R8 + self.Emit("MOVQ" , _R8, _VAR_sr) // MOVQ R8, sr + self.Sjmp("JMP" , "_end_{n}") // JMP _end_{n} + self.Link("_try_lowercase_{n}") // _try_lowercase_{n}: + self.Emit("MOVQ" , jit.Imm(referenceFields(p.vf())), _AX) // MOVQ ${p.vf()}, AX + self.Emit("MOVQ", _ARG_sv_p, _BX) // MOVQ sv, BX + self.Emit("MOVQ", _ARG_sv_n, _CX) // MOVQ sv, CX + self.call_go(_F_FieldMap_GetCaseInsensitive) // CALL_GO FieldMap::GetCaseInsensitive + self.Emit("MOVQ" , _AX, _VAR_sr) // MOVQ AX, _VAR_sr + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNS" , "_end_{n}") // JNS _end_{n} + self.Emit("BTQ" , jit.Imm(_F_disable_unknown), _ARG_fv) // BTQ ${_F_disable_unknown}, fv + self.Sjmp("JC" , _LB_field_error) // JC _field_error + self.Link("_end_{n}") // _end_{n}: +} + +func (self *_Assembler) _asm_OP_unmarshal(p *_Instr) { + self.unmarshal_json(p.vt(), true) +} + +func (self *_Assembler) _asm_OP_unmarshal_p(p *_Instr) { + self.unmarshal_json(p.vt(), false) +} + +func (self *_Assembler) _asm_OP_unmarshal_text(p *_Instr) { + self.unmarshal_text(p.vt(), true) +} + +func (self *_Assembler) _asm_OP_unmarshal_text_p(p *_Instr) { + self.unmarshal_text(p.vt(), false) +} + +func (self *_Assembler) _asm_OP_lspace(_ *_Instr) { + self.lspace("_{n}") +} + +func (self *_Assembler) lspace(subfix string) { + var label = "_lspace" + subfix + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , _LB_eof_error) // JAE _eof_error + self.Emit("MOVQ" , jit.Imm(_BM_space), _DX) // MOVQ _BM_space, DX + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' ' + self.Sjmp("JA" , label) // JA _nospace_{n} + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , label) // JNC _nospace_{n} + + /* test up to 4 characters */ + for i := 0; i < 3; i++ { + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , _LB_eof_error) // JAE _eof_error + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' ' + self.Sjmp("JA" , label) // JA _nospace_{n} + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , label) // JNC _nospace_{n} + } + + /* handle over to the native function */ + self.Emit("MOVQ" , _IP, _DI) // MOVQ IP, DI + self.Emit("MOVQ" , _IL, _SI) // MOVQ IL, SI + self.Emit("MOVQ" , _IC, _DX) // MOVQ IC, DX + self.callc(_F_lspace) // CALL lspace + self.Emit("TESTQ" , _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_parsing_error_v) // JS _parsing_error_v + self.Emit("CMPQ" , _AX, _IL) // CMPQ AX, IL + self.Sjmp("JAE" , _LB_eof_error) // JAE _eof_error + self.Emit("MOVQ" , _AX, _IC) // MOVQ AX, IC + self.Link(label) // _nospace_{n}: +} + +func (self *_Assembler) _asm_OP_match_char(p *_Instr) { + self.check_eof(1) + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(p.vb()))) // CMPB (IP)(IC), ${p.vb()} + self.Sjmp("JNE" , _LB_char_0_error) // JNE _char_0_error + self.Emit("ADDQ", jit.Imm(1), _IC) // ADDQ $1, IC +} + +func (self *_Assembler) _asm_OP_check_char(p *_Instr) { + self.check_eof(1) + self.Emit("LEAQ" , jit.Ptr(_IC, 1), _AX) // LEAQ 1(IC), AX + self.Emit("CMPB" , jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(p.vb()))) // CMPB (IP)(IC), ${p.vb()} + self.Emit("CMOVQEQ", _AX, _IC) // CMOVQEQ AX, IC + self.Xjmp("JE" , p.vi()) // JE {p.vi()} +} + +func (self *_Assembler) _asm_OP_check_char_0(p *_Instr) { + self.check_eof(1) + self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(p.vb()))) // CMPB (IP)(IC), ${p.vb()} + self.Xjmp("JE" , p.vi()) // JE {p.vi()} +} + +func (self *_Assembler) _asm_OP_add(p *_Instr) { + self.Emit("ADDQ", jit.Imm(int64(p.vi())), _IC) // ADDQ ${p.vi()}, IC +} + +func (self *_Assembler) _asm_OP_load(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, 0), _VP) // MOVQ (ST)(AX), VP +} + +func (self *_Assembler) _asm_OP_save(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _CX) // MOVQ (ST), CX + self.Emit("CMPQ", _CX, jit.Imm(_MaxStackBytes)) // CMPQ CX, ${_MaxStackBytes} + self.Sjmp("JAE" , _LB_stack_error) // JA _stack_error + self.WriteRecNotAX(0 , _VP, jit.Sib(_ST, _CX, 1, 8), false, false) // MOVQ VP, 8(ST)(CX) + self.Emit("ADDQ", jit.Imm(8), _CX) // ADDQ $8, CX + self.Emit("MOVQ", _CX, jit.Ptr(_ST, 0)) // MOVQ CX, (ST) +} + +func (self *_Assembler) _asm_OP_drop(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("SUBQ", jit.Imm(8), _AX) // SUBQ $8, AX + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, 8), _VP) // MOVQ 8(ST)(AX), VP + self.Emit("MOVQ", _AX, jit.Ptr(_ST, 0)) // MOVQ AX, (ST) + self.Emit("XORL", _BX, _BX) // XORL BX, BX + self.Emit("MOVQ", _BX, jit.Sib(_ST, _AX, 1, 8)) // MOVQ BX, 8(ST)(AX) +} + +func (self *_Assembler) _asm_OP_drop_2(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("SUBQ" , jit.Imm(16), _AX) // SUBQ $16, AX + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 8), _VP) // MOVQ 8(ST)(AX), VP + self.Emit("MOVQ" , _AX, jit.Ptr(_ST, 0)) // MOVQ AX, (ST) + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 8)) // MOVOU X0, 8(ST)(AX) +} + +func (self *_Assembler) _asm_OP_recurse(p *_Instr) { + self.Emit("MOVQ", jit.Type(p.vt()), _AX) // MOVQ ${p.vt()}, AX + self.decode_dynamic(_AX, _VP) // DECODE AX, VP +} + +func (self *_Assembler) _asm_OP_goto(p *_Instr) { + self.Xjmp("JMP", p.vi()) +} + +func (self *_Assembler) _asm_OP_switch(p *_Instr) { + self.Emit("MOVQ", _VAR_sr, _AX) // MOVQ sr, AX + self.Emit("CMPQ", _AX, jit.Imm(p.i64())) // CMPQ AX, ${len(p.vs())} + self.Sjmp("JAE" , "_default_{n}") // JAE _default_{n} + + /* jump table selector */ + self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI + self.Sref("_switch_table_{n}", 4) // .... &_switch_table_{n} + self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, 0), _AX) // MOVLQSX (DI)(AX*4), AX + self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX + self.Rjmp("JMP" , _AX) // JMP AX + self.Link("_switch_table_{n}") // _switch_table_{n}: + + /* generate the jump table */ + for i, v := range p.vs() { + self.Xref(v, int64(-i) * 4) + } + + /* default case */ + self.Link("_default_{n}") + self.NOP() +} + +func (self *_Assembler) print_gc(i int, p1 *_Instr, p2 *_Instr) { + self.Emit("MOVQ", jit.Imm(int64(p2.op())), _CX)// MOVQ $(p2.op()), 16(SP) + self.Emit("MOVQ", jit.Imm(int64(p1.op())), _BX) // MOVQ $(p1.op()), 8(SP) + self.Emit("MOVQ", jit.Imm(int64(i)), _AX) // MOVQ $(i), (SP) + self.call_go(_F_println) +} + +//go:linkname _runtime_writeBarrier runtime.writeBarrier +var _runtime_writeBarrier uintptr + +//go:linkname gcWriteBarrierAX runtime.gcWriteBarrier +func gcWriteBarrierAX() + +var ( + _V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&_runtime_writeBarrier)))) + + _F_gcWriteBarrierAX = jit.Func(gcWriteBarrierAX) +) + +func (self *_Assembler) WritePtrAX(i int, rec obj.Addr, saveDI bool) { + self.Emit("MOVQ", _V_writeBarrier, _R9) + self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + if saveDI { + self.save(_DI) + } + self.Emit("LEAQ", rec, _DI) + self.call(_F_gcWriteBarrierAX) + if saveDI { + self.load(_DI) + } + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", _AX, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} + +func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool, saveAX bool) { + if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { + panic("rec contains AX!") + } + self.Emit("MOVQ", _V_writeBarrier, _R9) + self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + if saveAX { + self.Emit("XCHGQ", ptr, _AX) + } else { + self.Emit("MOVQ", ptr, _AX) + } + if saveDI { + self.save(_DI) + } + self.Emit("LEAQ", rec, _DI) + self.call(_F_gcWriteBarrierAX) + if saveDI { + self.load(_DI) + } + if saveAX { + self.Emit("XCHGQ", ptr, _AX) + } + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", ptr, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/compiler.go b/ihub/vendor/github.com/bytedance/sonic/decoder/compiler.go new file mode 100644 index 0000000..b4fc2fe --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/compiler.go @@ -0,0 +1,1136 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `encoding/json` + `fmt` + `reflect` + `sort` + `strconv` + `strings` + `unsafe` + + `github.com/bytedance/sonic/internal/caching` + `github.com/bytedance/sonic/internal/resolver` + `github.com/bytedance/sonic/internal/rt` + `github.com/bytedance/sonic/option` +) + +type _Op uint8 + +const ( + _OP_any _Op = iota + 1 + _OP_dyn + _OP_str + _OP_bin + _OP_bool + _OP_num + _OP_i8 + _OP_i16 + _OP_i32 + _OP_i64 + _OP_u8 + _OP_u16 + _OP_u32 + _OP_u64 + _OP_f32 + _OP_f64 + _OP_unquote + _OP_nil_1 + _OP_nil_2 + _OP_nil_3 + _OP_deref + _OP_index + _OP_is_null + _OP_is_null_quote + _OP_map_init + _OP_map_key_i8 + _OP_map_key_i16 + _OP_map_key_i32 + _OP_map_key_i64 + _OP_map_key_u8 + _OP_map_key_u16 + _OP_map_key_u32 + _OP_map_key_u64 + _OP_map_key_f32 + _OP_map_key_f64 + _OP_map_key_str + _OP_map_key_utext + _OP_map_key_utext_p + _OP_array_skip + _OP_array_clear + _OP_array_clear_p + _OP_slice_init + _OP_slice_append + _OP_object_skip + _OP_object_next + _OP_struct_field + _OP_unmarshal + _OP_unmarshal_p + _OP_unmarshal_text + _OP_unmarshal_text_p + _OP_lspace + _OP_match_char + _OP_check_char + _OP_load + _OP_save + _OP_drop + _OP_drop_2 + _OP_recurse + _OP_goto + _OP_switch + _OP_check_char_0 + _OP_dismatch_err + _OP_go_skip + _OP_add + _OP_debug +) + +const ( + _INT_SIZE = 32 << (^uint(0) >> 63) + _PTR_SIZE = 32 << (^uintptr(0) >> 63) + _PTR_BYTE = unsafe.Sizeof(uintptr(0)) +) + +const ( + _MAX_ILBUF = 100000 // cutoff at 100k of IL instructions + _MAX_FIELDS = 50 // cutoff at 50 fields struct +) + +var _OpNames = [256]string { + _OP_any : "any", + _OP_dyn : "dyn", + _OP_str : "str", + _OP_bin : "bin", + _OP_bool : "bool", + _OP_num : "num", + _OP_i8 : "i8", + _OP_i16 : "i16", + _OP_i32 : "i32", + _OP_i64 : "i64", + _OP_u8 : "u8", + _OP_u16 : "u16", + _OP_u32 : "u32", + _OP_u64 : "u64", + _OP_f32 : "f32", + _OP_f64 : "f64", + _OP_unquote : "unquote", + _OP_nil_1 : "nil_1", + _OP_nil_2 : "nil_2", + _OP_nil_3 : "nil_3", + _OP_deref : "deref", + _OP_index : "index", + _OP_is_null : "is_null", + _OP_is_null_quote : "is_null_quote", + _OP_map_init : "map_init", + _OP_map_key_i8 : "map_key_i8", + _OP_map_key_i16 : "map_key_i16", + _OP_map_key_i32 : "map_key_i32", + _OP_map_key_i64 : "map_key_i64", + _OP_map_key_u8 : "map_key_u8", + _OP_map_key_u16 : "map_key_u16", + _OP_map_key_u32 : "map_key_u32", + _OP_map_key_u64 : "map_key_u64", + _OP_map_key_f32 : "map_key_f32", + _OP_map_key_f64 : "map_key_f64", + _OP_map_key_str : "map_key_str", + _OP_map_key_utext : "map_key_utext", + _OP_map_key_utext_p : "map_key_utext_p", + _OP_array_skip : "array_skip", + _OP_slice_init : "slice_init", + _OP_slice_append : "slice_append", + _OP_object_skip : "object_skip", + _OP_object_next : "object_next", + _OP_struct_field : "struct_field", + _OP_unmarshal : "unmarshal", + _OP_unmarshal_p : "unmarshal_p", + _OP_unmarshal_text : "unmarshal_text", + _OP_unmarshal_text_p : "unmarshal_text_p", + _OP_lspace : "lspace", + _OP_match_char : "match_char", + _OP_check_char : "check_char", + _OP_load : "load", + _OP_save : "save", + _OP_drop : "drop", + _OP_drop_2 : "drop_2", + _OP_recurse : "recurse", + _OP_goto : "goto", + _OP_switch : "switch", + _OP_check_char_0 : "check_char_0", + _OP_dismatch_err : "dismatch_err", + _OP_add : "add", +} + +func (self _Op) String() string { + if ret := _OpNames[self]; ret != "" { + return ret + } else { + return "" + } +} + +func _OP_int() _Op { + switch _INT_SIZE { + case 32: return _OP_i32 + case 64: return _OP_i64 + default: panic("unsupported int size") + } +} + +func _OP_uint() _Op { + switch _INT_SIZE { + case 32: return _OP_u32 + case 64: return _OP_u64 + default: panic("unsupported uint size") + } +} + +func _OP_uintptr() _Op { + switch _PTR_SIZE { + case 32: return _OP_u32 + case 64: return _OP_u64 + default: panic("unsupported pointer size") + } +} + +func _OP_map_key_int() _Op { + switch _INT_SIZE { + case 32: return _OP_map_key_i32 + case 64: return _OP_map_key_i64 + default: panic("unsupported int size") + } +} + +func _OP_map_key_uint() _Op { + switch _INT_SIZE { + case 32: return _OP_map_key_u32 + case 64: return _OP_map_key_u64 + default: panic("unsupported uint size") + } +} + +func _OP_map_key_uintptr() _Op { + switch _PTR_SIZE { + case 32: return _OP_map_key_u32 + case 64: return _OP_map_key_u64 + default: panic("unsupported pointer size") + } +} + +type _Instr struct { + u uint64 // union {op: 8, vb: 8, vi: 48}, iv maybe int or len([]int) + p unsafe.Pointer // maybe GoSlice.Data, *GoType or *caching.FieldMap +} + +func packOp(op _Op) uint64 { + return uint64(op) << 56 +} + +func newInsOp(op _Op) _Instr { + return _Instr{u: packOp(op)} +} + +func newInsVi(op _Op, vi int) _Instr { + return _Instr{u: packOp(op) | rt.PackInt(vi)} +} + +func newInsVb(op _Op, vb byte) _Instr { + return _Instr{u: packOp(op) | (uint64(vb) << 48)} +} + +func newInsVs(op _Op, vs []int) _Instr { + return _Instr { + u: packOp(op) | rt.PackInt(len(vs)), + p: (*rt.GoSlice)(unsafe.Pointer(&vs)).Ptr, + } +} + +func newInsVt(op _Op, vt reflect.Type) _Instr { + return _Instr { + u: packOp(op), + p: unsafe.Pointer(rt.UnpackType(vt)), + } +} + +func newInsVf(op _Op, vf *caching.FieldMap) _Instr { + return _Instr { + u: packOp(op), + p: unsafe.Pointer(vf), + } +} + +func (self _Instr) op() _Op { + return _Op(self.u >> 56) +} + +func (self _Instr) vi() int { + return rt.UnpackInt(self.u) +} + +func (self _Instr) vb() byte { + return byte(self.u >> 48) +} + +func (self _Instr) vs() (v []int) { + (*rt.GoSlice)(unsafe.Pointer(&v)).Ptr = self.p + (*rt.GoSlice)(unsafe.Pointer(&v)).Cap = self.vi() + (*rt.GoSlice)(unsafe.Pointer(&v)).Len = self.vi() + return +} + +func (self _Instr) vf() *caching.FieldMap { + return (*caching.FieldMap)(self.p) +} + +func (self _Instr) vk() reflect.Kind { + return (*rt.GoType)(self.p).Kind() +} + +func (self _Instr) vt() reflect.Type { + return (*rt.GoType)(self.p).Pack() +} + +func (self _Instr) i64() int64 { + return int64(self.vi()) +} + +func (self _Instr) vlen() int { + return int((*rt.GoType)(self.p).Size) +} + +func (self _Instr) isBranch() bool { + switch self.op() { + case _OP_goto : fallthrough + case _OP_switch : fallthrough + case _OP_is_null : fallthrough + case _OP_is_null_quote : fallthrough + case _OP_check_char : return true + default : return false + } +} + +func (self _Instr) disassemble() string { + switch self.op() { + case _OP_dyn : fallthrough + case _OP_deref : fallthrough + case _OP_map_key_i8 : fallthrough + case _OP_map_key_i16 : fallthrough + case _OP_map_key_i32 : fallthrough + case _OP_map_key_i64 : fallthrough + case _OP_map_key_u8 : fallthrough + case _OP_map_key_u16 : fallthrough + case _OP_map_key_u32 : fallthrough + case _OP_map_key_u64 : fallthrough + case _OP_map_key_f32 : fallthrough + case _OP_map_key_f64 : fallthrough + case _OP_map_key_str : fallthrough + case _OP_map_key_utext : fallthrough + case _OP_map_key_utext_p : fallthrough + case _OP_slice_init : fallthrough + case _OP_slice_append : fallthrough + case _OP_unmarshal : fallthrough + case _OP_unmarshal_p : fallthrough + case _OP_unmarshal_text : fallthrough + case _OP_unmarshal_text_p : fallthrough + case _OP_recurse : return fmt.Sprintf("%-18s%s", self.op(), self.vt()) + case _OP_goto : fallthrough + case _OP_is_null_quote : fallthrough + case _OP_is_null : return fmt.Sprintf("%-18sL_%d", self.op(), self.vi()) + case _OP_index : fallthrough + case _OP_array_clear : fallthrough + case _OP_array_clear_p : return fmt.Sprintf("%-18s%d", self.op(), self.vi()) + case _OP_switch : return fmt.Sprintf("%-18s%s", self.op(), self.formatSwitchLabels()) + case _OP_struct_field : return fmt.Sprintf("%-18s%s", self.op(), self.formatStructFields()) + case _OP_match_char : return fmt.Sprintf("%-18s%s", self.op(), strconv.QuoteRune(rune(self.vb()))) + case _OP_check_char : return fmt.Sprintf("%-18sL_%d, %s", self.op(), self.vi(), strconv.QuoteRune(rune(self.vb()))) + default : return self.op().String() + } +} + +func (self _Instr) formatSwitchLabels() string { + var i int + var v int + var m []string + + /* format each label */ + for i, v = range self.vs() { + m = append(m, fmt.Sprintf("%d=L_%d", i, v)) + } + + /* join them with "," */ + return strings.Join(m, ", ") +} + +func (self _Instr) formatStructFields() string { + var i uint64 + var r []string + var m []struct{i int; n string} + + /* extract all the fields */ + for i = 0; i < self.vf().N; i++ { + if v := self.vf().At(i); v.Hash != 0 { + m = append(m, struct{i int; n string}{i: v.ID, n: v.Name}) + } + } + + /* sort by field name */ + sort.Slice(m, func(i, j int) bool { + return m[i].n < m[j].n + }) + + /* format each field */ + for _, v := range m { + r = append(r, fmt.Sprintf("%s=%d", v.n, v.i)) + } + + /* join them with "," */ + return strings.Join(r, ", ") +} + +type ( + _Program []_Instr +) + +func (self _Program) pc() int { + return len(self) +} + +func (self _Program) tag(n int) { + if n >= _MaxStack { + panic("type nesting too deep") + } +} + +func (self _Program) pin(i int) { + v := &self[i] + v.u &= 0xffff000000000000 + v.u |= rt.PackInt(self.pc()) +} + +func (self _Program) rel(v []int) { + for _, i := range v { + self.pin(i) + } +} + +func (self *_Program) add(op _Op) { + *self = append(*self, newInsOp(op)) +} + +func (self *_Program) int(op _Op, vi int) { + *self = append(*self, newInsVi(op, vi)) +} + +func (self *_Program) chr(op _Op, vb byte) { + *self = append(*self, newInsVb(op, vb)) +} + +func (self *_Program) tab(op _Op, vs []int) { + *self = append(*self, newInsVs(op, vs)) +} + +func (self *_Program) rtt(op _Op, vt reflect.Type) { + *self = append(*self, newInsVt(op, vt)) +} + +func (self *_Program) fmv(op _Op, vf *caching.FieldMap) { + *self = append(*self, newInsVf(op, vf)) +} + +func (self _Program) disassemble() string { + nb := len(self) + tab := make([]bool, nb + 1) + ret := make([]string, 0, nb + 1) + + /* prescan to get all the labels */ + for _, ins := range self { + if ins.isBranch() { + if ins.op() != _OP_switch { + tab[ins.vi()] = true + } else { + for _, v := range ins.vs() { + tab[v] = true + } + } + } + } + + /* disassemble each instruction */ + for i, ins := range self { + if !tab[i] { + ret = append(ret, "\t" + ins.disassemble()) + } else { + ret = append(ret, fmt.Sprintf("L_%d:\n\t%s", i, ins.disassemble())) + } + } + + /* add the last label, if needed */ + if tab[nb] { + ret = append(ret, fmt.Sprintf("L_%d:", nb)) + } + + /* add an "end" indicator, and join all the strings */ + return strings.Join(append(ret, "\tend"), "\n") +} + +type _Compiler struct { + opts option.CompileOptions + tab map[reflect.Type]bool + rec map[reflect.Type]bool +} + +func newCompiler() *_Compiler { + return &_Compiler { + opts: option.DefaultCompileOptions(), + tab: map[reflect.Type]bool{}, + rec: map[reflect.Type]bool{}, + } +} + +func (self *_Compiler) apply(opts option.CompileOptions) *_Compiler { + self.opts = opts + return self +} + +func (self *_Compiler) rescue(ep *error) { + if val := recover(); val != nil { + if err, ok := val.(error); ok { + *ep = err + } else { + panic(val) + } + } +} + +func (self *_Compiler) compile(vt reflect.Type) (ret _Program, err error) { + defer self.rescue(&err) + self.compileOne(&ret, 0, vt) + return +} + +func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) { + /* check for recursive nesting */ + ok := self.tab[vt] + if ok { + p.rtt(_OP_recurse, vt) + return + } + + pt := reflect.PtrTo(vt) + + /* check for `json.Unmarshaler` with pointer receiver */ + if pt.Implements(jsonUnmarshalerType) { + p.rtt(_OP_unmarshal_p, pt) + return + } + + /* check for `json.Unmarshaler` */ + if vt.Implements(jsonUnmarshalerType) { + p.add(_OP_lspace) + self.compileUnmarshalJson(p, vt) + return + } + + /* check for `encoding.TextMarshaler` with pointer receiver */ + if pt.Implements(encodingTextUnmarshalerType) { + p.add(_OP_lspace) + self.compileUnmarshalTextPtr(p, pt) + return + } + + /* check for `encoding.TextUnmarshaler` */ + if vt.Implements(encodingTextUnmarshalerType) { + p.add(_OP_lspace) + self.compileUnmarshalText(p, vt) + return + } + + /* enter the recursion */ + p.add(_OP_lspace) + self.tab[vt] = true + self.compileOps(p, sp, vt) + delete(self.tab, vt) +} + +func (self *_Compiler) compileOps(p *_Program, sp int, vt reflect.Type) { + switch vt.Kind() { + case reflect.Bool : self.compilePrimitive (vt, p, _OP_bool) + case reflect.Int : self.compilePrimitive (vt, p, _OP_int()) + case reflect.Int8 : self.compilePrimitive (vt, p, _OP_i8) + case reflect.Int16 : self.compilePrimitive (vt, p, _OP_i16) + case reflect.Int32 : self.compilePrimitive (vt, p, _OP_i32) + case reflect.Int64 : self.compilePrimitive (vt, p, _OP_i64) + case reflect.Uint : self.compilePrimitive (vt, p, _OP_uint()) + case reflect.Uint8 : self.compilePrimitive (vt, p, _OP_u8) + case reflect.Uint16 : self.compilePrimitive (vt, p, _OP_u16) + case reflect.Uint32 : self.compilePrimitive (vt, p, _OP_u32) + case reflect.Uint64 : self.compilePrimitive (vt, p, _OP_u64) + case reflect.Uintptr : self.compilePrimitive (vt, p, _OP_uintptr()) + case reflect.Float32 : self.compilePrimitive (vt, p, _OP_f32) + case reflect.Float64 : self.compilePrimitive (vt, p, _OP_f64) + case reflect.String : self.compileString (p, vt) + case reflect.Array : self.compileArray (p, sp, vt) + case reflect.Interface : self.compileInterface (p, vt) + case reflect.Map : self.compileMap (p, sp, vt) + case reflect.Ptr : self.compilePtr (p, sp, vt) + case reflect.Slice : self.compileSlice (p, sp, vt) + case reflect.Struct : self.compileStruct (p, sp, vt) + default : panic (&json.UnmarshalTypeError{Type: vt}) + } +} + +func (self *_Compiler) compileMap(p *_Program, sp int, vt reflect.Type) { + if reflect.PtrTo(vt.Key()).Implements(encodingTextUnmarshalerType) { + self.compileMapOp(p, sp, vt, _OP_map_key_utext_p) + } else if vt.Key().Implements(encodingTextUnmarshalerType) { + self.compileMapOp(p, sp, vt, _OP_map_key_utext) + } else { + self.compileMapUt(p, sp, vt) + } +} + +func (self *_Compiler) compileMapUt(p *_Program, sp int, vt reflect.Type) { + switch vt.Key().Kind() { + case reflect.Int : self.compileMapOp(p, sp, vt, _OP_map_key_int()) + case reflect.Int8 : self.compileMapOp(p, sp, vt, _OP_map_key_i8) + case reflect.Int16 : self.compileMapOp(p, sp, vt, _OP_map_key_i16) + case reflect.Int32 : self.compileMapOp(p, sp, vt, _OP_map_key_i32) + case reflect.Int64 : self.compileMapOp(p, sp, vt, _OP_map_key_i64) + case reflect.Uint : self.compileMapOp(p, sp, vt, _OP_map_key_uint()) + case reflect.Uint8 : self.compileMapOp(p, sp, vt, _OP_map_key_u8) + case reflect.Uint16 : self.compileMapOp(p, sp, vt, _OP_map_key_u16) + case reflect.Uint32 : self.compileMapOp(p, sp, vt, _OP_map_key_u32) + case reflect.Uint64 : self.compileMapOp(p, sp, vt, _OP_map_key_u64) + case reflect.Uintptr : self.compileMapOp(p, sp, vt, _OP_map_key_uintptr()) + case reflect.Float32 : self.compileMapOp(p, sp, vt, _OP_map_key_f32) + case reflect.Float64 : self.compileMapOp(p, sp, vt, _OP_map_key_f64) + case reflect.String : self.compileMapOp(p, sp, vt, _OP_map_key_str) + default : panic(&json.UnmarshalTypeError{Type: vt}) + } +} + +func (self *_Compiler) compileMapOp(p *_Program, sp int, vt reflect.Type, op _Op) { + i := p.pc() + p.add(_OP_is_null) + p.tag(sp + 1) + skip := self.checkIfSkip(p, vt, '{') + p.add(_OP_save) + p.add(_OP_map_init) + p.add(_OP_save) + p.add(_OP_lspace) + j := p.pc() + p.chr(_OP_check_char, '}') + p.chr(_OP_match_char, '"') + skip2 := p.pc() + p.rtt(op, vt) + + /* match the closing quote if needed */ + if op != _OP_map_key_str && op != _OP_map_key_utext && op != _OP_map_key_utext_p { + p.chr(_OP_match_char, '"') + } + + /* match the value separator */ + p.add(_OP_lspace) + p.chr(_OP_match_char, ':') + self.compileOne(p, sp + 2, vt.Elem()) + p.pin(skip2) + p.add(_OP_load) + k0 := p.pc() + p.add(_OP_lspace) + k1 := p.pc() + p.chr(_OP_check_char, '}') + p.chr(_OP_match_char, ',') + p.add(_OP_lspace) + p.chr(_OP_match_char, '"') + skip3 := p.pc() + p.rtt(op, vt) + + /* match the closing quote if needed */ + if op != _OP_map_key_str && op != _OP_map_key_utext && op != _OP_map_key_utext_p { + p.chr(_OP_match_char, '"') + } + + /* match the value separator */ + p.add(_OP_lspace) + p.chr(_OP_match_char, ':') + self.compileOne(p, sp + 2, vt.Elem()) + p.pin(skip3) + p.add(_OP_load) + p.int(_OP_goto, k0) + p.pin(j) + p.pin(k1) + p.add(_OP_drop_2) + x := p.pc() + p.add(_OP_goto) + p.pin(i) + p.add(_OP_nil_1) + p.pin(skip) + p.pin(x) +} + +func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) { + i := p.pc() + p.add(_OP_is_null) + + /* dereference all the way down */ + for et.Kind() == reflect.Ptr { + et = et.Elem() + p.rtt(_OP_deref, et) + } + + /* compile the element type */ + self.compileOne(p, sp + 1, et) + j := p.pc() + p.add(_OP_goto) + p.pin(i) + p.add(_OP_nil_1) + p.pin(j) +} + +func (self *_Compiler) compileArray(p *_Program, sp int, vt reflect.Type) { + x := p.pc() + p.add(_OP_is_null) + p.tag(sp) + skip := self.checkIfSkip(p, vt, '[') + + p.add(_OP_save) + p.add(_OP_lspace) + v := []int{p.pc()} + p.chr(_OP_check_char, ']') + + /* decode every item */ + for i := 1; i <= vt.Len(); i++ { + self.compileOne(p, sp + 1, vt.Elem()) + p.add(_OP_load) + p.int(_OP_index, i * int(vt.Elem().Size())) + p.add(_OP_lspace) + v = append(v, p.pc()) + p.chr(_OP_check_char, ']') + p.chr(_OP_match_char, ',') + } + + /* drop rest of the array */ + p.add(_OP_array_skip) + w := p.pc() + p.add(_OP_goto) + p.rel(v) + + /* check for pointer data */ + if rt.UnpackType(vt.Elem()).PtrData == 0 { + p.int(_OP_array_clear, int(vt.Size())) + } else { + p.int(_OP_array_clear_p, int(vt.Size())) + } + + /* restore the stack */ + p.pin(w) + p.add(_OP_drop) + + p.pin(skip) + p.pin(x) +} + +func (self *_Compiler) compileSlice(p *_Program, sp int, vt reflect.Type) { + if vt.Elem().Kind() == byteType.Kind() { + self.compileSliceBin(p, sp, vt) + } else { + self.compileSliceList(p, sp, vt) + } +} + +func (self *_Compiler) compileSliceBin(p *_Program, sp int, vt reflect.Type) { + i := p.pc() + p.add(_OP_is_null) + j := p.pc() + p.chr(_OP_check_char, '[') + skip := self.checkIfSkip(p, vt, '"') + k := p.pc() + p.chr(_OP_check_char, '"') + p.add(_OP_bin) + x := p.pc() + p.add(_OP_goto) + p.pin(j) + self.compileSliceBody(p, sp, vt.Elem()) + y := p.pc() + p.add(_OP_goto) + p.pin(i) + p.pin(k) + p.add(_OP_nil_3) + p.pin(x) + p.pin(skip) + p.pin(y) +} + +func (self *_Compiler) compileSliceList(p *_Program, sp int, vt reflect.Type) { + i := p.pc() + p.add(_OP_is_null) + p.tag(sp) + skip := self.checkIfSkip(p, vt, '[') + self.compileSliceBody(p, sp, vt.Elem()) + x := p.pc() + p.add(_OP_goto) + p.pin(i) + p.add(_OP_nil_3) + p.pin(x) + p.pin(skip) +} + +func (self *_Compiler) compileSliceBody(p *_Program, sp int, et reflect.Type) { + p.rtt(_OP_slice_init, et) + p.add(_OP_save) + p.add(_OP_lspace) + j := p.pc() + p.chr(_OP_check_char, ']') + p.rtt(_OP_slice_append, et) + self.compileOne(p, sp + 1, et) + p.add(_OP_load) + k0 := p.pc() + p.add(_OP_lspace) + k1 := p.pc() + p.chr(_OP_check_char, ']') + p.chr(_OP_match_char, ',') + p.rtt(_OP_slice_append, et) + self.compileOne(p, sp + 1, et) + p.add(_OP_load) + p.int(_OP_goto, k0) + p.pin(j) + p.pin(k1) + p.add(_OP_drop) +} + +func (self *_Compiler) compileString(p *_Program, vt reflect.Type) { + if vt == jsonNumberType { + self.compilePrimitive(vt, p, _OP_num) + } else { + self.compileStringBody(vt, p) + } +} + +func (self *_Compiler) compileStringBody(vt reflect.Type, p *_Program) { + i := p.pc() + p.add(_OP_is_null) + skip := self.checkIfSkip(p, vt, '"') + p.add(_OP_str) + p.pin(i) + p.pin(skip) +} + +func (self *_Compiler) compileStruct(p *_Program, sp int, vt reflect.Type) { + if sp >= self.opts.MaxInlineDepth || p.pc() >= _MAX_ILBUF || (sp > 0 && vt.NumField() >= _MAX_FIELDS) { + p.rtt(_OP_recurse, vt) + if self.opts.RecursiveDepth > 0 { + self.rec[vt] = true + } + } else { + self.compileStructBody(p, sp, vt) + } +} + +func (self *_Compiler) compileStructBody(p *_Program, sp int, vt reflect.Type) { + fv := resolver.ResolveStruct(vt) + fm, sw := caching.CreateFieldMap(len(fv)), make([]int, len(fv)) + + /* start of object */ + p.tag(sp) + n := p.pc() + p.add(_OP_is_null) + + skip := self.checkIfSkip(p, vt, '{') + + p.add(_OP_save) + p.add(_OP_lspace) + x := p.pc() + p.chr(_OP_check_char, '}') + p.chr(_OP_match_char, '"') + p.fmv(_OP_struct_field, fm) + p.add(_OP_lspace) + p.chr(_OP_match_char, ':') + p.tab(_OP_switch, sw) + p.add(_OP_object_next) + y0 := p.pc() + p.add(_OP_lspace) + y1 := p.pc() + p.chr(_OP_check_char, '}') + p.chr(_OP_match_char, ',') + + /* special case of an empty struct */ + if len(fv) == 0 { + p.add(_OP_object_skip) + goto end_of_object + } + + /* match the remaining fields */ + p.add(_OP_lspace) + p.chr(_OP_match_char, '"') + p.fmv(_OP_struct_field, fm) + p.add(_OP_lspace) + p.chr(_OP_match_char, ':') + p.tab(_OP_switch, sw) + p.add(_OP_object_next) + p.int(_OP_goto, y0) + + /* process each field */ + for i, f := range fv { + sw[i] = p.pc() + fm.Set(f.Name, i) + + /* index to the field */ + for _, o := range f.Path { + if p.int(_OP_index, int(o.Size)); o.Kind == resolver.F_deref { + p.rtt(_OP_deref, o.Type) + } + } + + /* check for "stringnize" option */ + if (f.Opts & resolver.F_stringize) == 0 { + self.compileOne(p, sp + 1, f.Type) + } else { + self.compileStructFieldStr(p, sp + 1, f.Type) + } + + /* load the state, and try next field */ + p.add(_OP_load) + p.int(_OP_goto, y0) + } + +end_of_object: + p.pin(x) + p.pin(y1) + p.add(_OP_drop) + p.pin(n) + p.pin(skip) +} + +func (self *_Compiler) compileStructFieldStr(p *_Program, sp int, vt reflect.Type) { + n1 := -1 + ft := vt + sv := false + + /* dereference the pointer if needed */ + if ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + + /* check if it can be stringized */ + switch ft.Kind() { + case reflect.Bool : sv = true + case reflect.Int : sv = true + case reflect.Int8 : sv = true + case reflect.Int16 : sv = true + case reflect.Int32 : sv = true + case reflect.Int64 : sv = true + case reflect.Uint : sv = true + case reflect.Uint8 : sv = true + case reflect.Uint16 : sv = true + case reflect.Uint32 : sv = true + case reflect.Uint64 : sv = true + case reflect.Uintptr : sv = true + case reflect.Float32 : sv = true + case reflect.Float64 : sv = true + case reflect.String : sv = true + } + + /* if it's not, ignore the "string" and follow the regular path */ + if !sv { + self.compileOne(p, sp, vt) + return + } + + /* remove the leading space, and match the leading quote */ + vk := vt.Kind() + p.add(_OP_lspace) + n0 := p.pc() + p.add(_OP_is_null) + + skip := self.checkIfSkip(p, stringType, '"') + + /* also check for inner "null" */ + n1 = p.pc() + p.add(_OP_is_null_quote) + + /* dereference the pointer only when it is not null */ + if vk == reflect.Ptr { + vt = vt.Elem() + p.rtt(_OP_deref, vt) + } + + n2 := p.pc() + p.chr(_OP_check_char_0, '"') + + /* string opcode selector */ + _OP_string := func() _Op { + if ft == jsonNumberType { + return _OP_num + } else { + return _OP_unquote + } + } + + /* compile for each type */ + switch vt.Kind() { + case reflect.Bool : p.add(_OP_bool) + case reflect.Int : p.add(_OP_int()) + case reflect.Int8 : p.add(_OP_i8) + case reflect.Int16 : p.add(_OP_i16) + case reflect.Int32 : p.add(_OP_i32) + case reflect.Int64 : p.add(_OP_i64) + case reflect.Uint : p.add(_OP_uint()) + case reflect.Uint8 : p.add(_OP_u8) + case reflect.Uint16 : p.add(_OP_u16) + case reflect.Uint32 : p.add(_OP_u32) + case reflect.Uint64 : p.add(_OP_u64) + case reflect.Uintptr : p.add(_OP_uintptr()) + case reflect.Float32 : p.add(_OP_f32) + case reflect.Float64 : p.add(_OP_f64) + case reflect.String : p.add(_OP_string()) + default : panic("not reachable") + } + + /* the closing quote is not needed when parsing a pure string */ + if vt == jsonNumberType || vt.Kind() != reflect.String { + p.chr(_OP_match_char, '"') + } + + /* pin the `is_null_quote` jump location */ + if n1 != -1 && vk != reflect.Ptr { + p.pin(n1) + } + + /* "null" but not a pointer, act as if the field is not present */ + if vk != reflect.Ptr { + pc2 := p.pc() + p.add(_OP_goto) + p.pin(n2) + p.rtt(_OP_dismatch_err, vt) + p.int(_OP_add, 1) + p.pin(pc2) + p.pin(n0) + return + } + + /* the "null" case of the pointer */ + pc := p.pc() + p.add(_OP_goto) + p.pin(n0) // `is_null` jump location + p.pin(n1) // `is_null_quote` jump location + p.add(_OP_nil_1) + pc2 := p.pc() + p.add(_OP_goto) + p.pin(n2) + p.rtt(_OP_dismatch_err, vt) + p.int(_OP_add, 1) + p.pin(pc) + p.pin(pc2) + p.pin(skip) +} + +func (self *_Compiler) compileInterface(p *_Program, vt reflect.Type) { + i := p.pc() + p.add(_OP_is_null) + + /* check for empty interface */ + if vt.NumMethod() == 0 { + p.add(_OP_any) + } else { + p.rtt(_OP_dyn, vt) + } + + /* finish the OpCode */ + j := p.pc() + p.add(_OP_goto) + p.pin(i) + p.add(_OP_nil_2) + p.pin(j) +} + +func (self *_Compiler) compilePrimitive(vt reflect.Type, p *_Program, op _Op) { + i := p.pc() + p.add(_OP_is_null) + // skip := self.checkPrimitive(p, vt) + p.add(op) + p.pin(i) + // p.pin(skip) +} + +func (self *_Compiler) compileUnmarshalEnd(p *_Program, vt reflect.Type, i int) { + j := p.pc() + k := vt.Kind() + + /* not a pointer */ + if k != reflect.Ptr { + p.pin(i) + return + } + + /* it seems that in Go JSON library, "null" takes priority over any kind of unmarshaler */ + p.add(_OP_goto) + p.pin(i) + p.add(_OP_nil_1) + p.pin(j) +} + +func (self *_Compiler) compileUnmarshalJson(p *_Program, vt reflect.Type) { + i := p.pc() + v := _OP_unmarshal + p.add(_OP_is_null) + + /* check for dynamic interface */ + if vt.Kind() == reflect.Interface { + v = _OP_dyn + } + + /* call the unmarshaler */ + p.rtt(v, vt) + self.compileUnmarshalEnd(p, vt, i) +} + +func (self *_Compiler) compileUnmarshalText(p *_Program, vt reflect.Type) { + i := p.pc() + v := _OP_unmarshal_text + p.add(_OP_is_null) + + /* check for dynamic interface */ + if vt.Kind() == reflect.Interface { + v = _OP_dyn + } else { + p.chr(_OP_match_char, '"') + } + + /* call the unmarshaler */ + p.rtt(v, vt) + self.compileUnmarshalEnd(p, vt, i) +} + +func (self *_Compiler) compileUnmarshalTextPtr(p *_Program, vt reflect.Type) { + i := p.pc() + p.add(_OP_is_null) + p.chr(_OP_match_char, '"') + p.rtt(_OP_unmarshal_text_p, vt) + p.pin(i) +} + +func (self *_Compiler) checkIfSkip(p *_Program, vt reflect.Type, c byte) int { + j := p.pc() + p.chr(_OP_check_char_0, c) + p.rtt(_OP_dismatch_err, vt) + s := p.pc() + p.add(_OP_go_skip) + p.pin(j) + p.int(_OP_add, 1) + return s +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/debug.go b/ihub/vendor/github.com/bytedance/sonic/decoder/debug.go new file mode 100644 index 0000000..9cf3a6a --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/debug.go @@ -0,0 +1,70 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `os` + `runtime` + `runtime/debug` + `strings` + + `github.com/bytedance/sonic/internal/jit` +) + + +var ( + debugSyncGC = os.Getenv("SONIC_SYNC_GC") != "" + debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == "" +) + +var ( + _Instr_End _Instr = newInsOp(_OP_nil_1) + + _F_gc = jit.Func(runtime.GC) + _F_force_gc = jit.Func(debug.FreeOSMemory) + _F_println = jit.Func(println_wrapper) + _F_print = jit.Func(print) +) + +func println_wrapper(i int, op1 int, op2 int){ + println(i, " Intrs ", op1, _OpNames[op1], "next: ", op2, _OpNames[op2]) +} + +func print(i int){ + println(i) +} + +func (self *_Assembler) force_gc() { + self.call_go(_F_gc) + self.call_go(_F_force_gc) +} + +func (self *_Assembler) debug_instr(i int, v *_Instr) { + if debugSyncGC { + if (i+1 == len(self.p)) { + self.print_gc(i, v, &_Instr_End) + } else { + next := &(self.p[i+1]) + self.print_gc(i, v, next) + name := _OpNames[next.op()] + if strings.Contains(name, "save") { + return + } + } + self.force_gc() + } +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/decoder.go b/ihub/vendor/github.com/bytedance/sonic/decoder/decoder.go new file mode 100644 index 0000000..5326f97 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/decoder.go @@ -0,0 +1,245 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `encoding/json` + `reflect` + `runtime` + + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` + `github.com/bytedance/sonic/option` + `github.com/bytedance/sonic/utf8` +) + +const ( + _F_use_int64 = iota + _F_use_number + _F_disable_urc + _F_disable_unknown + _F_copy_string + _F_validate_string + + _F_allow_control = 31 +) + +type Options uint64 + +const ( + OptionUseInt64 Options = 1 << _F_use_int64 + OptionUseNumber Options = 1 << _F_use_number + OptionUseUnicodeErrors Options = 1 << _F_disable_urc + OptionDisableUnknown Options = 1 << _F_disable_unknown + OptionCopyString Options = 1 << _F_copy_string + OptionValidateString Options = 1 << _F_validate_string +) + +func (self *Decoder) SetOptions(opts Options) { + if (opts & OptionUseNumber != 0) && (opts & OptionUseInt64 != 0) { + panic("can't set OptionUseInt64 and OptionUseNumber both!") + } + self.f = uint64(opts) +} + + +// Decoder is the decoder context object +type Decoder struct { + i int + f uint64 + s string +} + +// NewDecoder creates a new decoder instance. +func NewDecoder(s string) *Decoder { + return &Decoder{s: s} +} + +// Pos returns the current decoding position. +func (self *Decoder) Pos() int { + return self.i +} + +func (self *Decoder) Reset(s string) { + self.s = s + self.i = 0 + // self.f = 0 +} + +func (self *Decoder) CheckTrailings() error { + pos := self.i + buf := self.s + /* skip all the trailing spaces */ + if pos != len(buf) { + for pos < len(buf) && (types.SPACE_MASK & (1 << buf[pos])) != 0 { + pos++ + } + } + + /* then it must be at EOF */ + if pos == len(buf) { + return nil + } + + /* junk after JSON value */ + return SyntaxError { + Src : buf, + Pos : pos, + Code : types.ERR_INVALID_CHAR, + } +} + + +// Decode parses the JSON-encoded data from current position and stores the result +// in the value pointed to by val. +func (self *Decoder) Decode(val interface{}) error { + /* validate json if needed */ + if (self.f & (1 << _F_validate_string)) != 0 && !utf8.ValidateString(self.s){ + dbuf := utf8.CorrectWith(nil, rt.Str2Mem(self.s), "\ufffd") + self.s = rt.Mem2Str(dbuf) + } + + vv := rt.UnpackEface(val) + vp := vv.Value + + /* check for nil type */ + if vv.Type == nil { + return &json.InvalidUnmarshalError{} + } + + /* must be a non-nil pointer */ + if vp == nil || vv.Type.Kind() != reflect.Ptr { + return &json.InvalidUnmarshalError{Type: vv.Type.Pack()} + } + + /* create a new stack, and call the decoder */ + sb, etp := newStack(), rt.PtrElem(vv.Type) + nb, err := decodeTypedPointer(self.s, self.i, etp, vp, sb, self.f) + /* return the stack back */ + self.i = nb + freeStack(sb) + + /* avoid GC ahead */ + runtime.KeepAlive(vv) + return err +} + +// UseInt64 indicates the Decoder to unmarshal an integer into an interface{} as an +// int64 instead of as a float64. +func (self *Decoder) UseInt64() { + self.f |= 1 << _F_use_int64 + self.f &^= 1 << _F_use_number +} + +// UseNumber indicates the Decoder to unmarshal a number into an interface{} as a +// json.Number instead of as a float64. +func (self *Decoder) UseNumber() { + self.f &^= 1 << _F_use_int64 + self.f |= 1 << _F_use_number +} + +// UseUnicodeErrors indicates the Decoder to return an error when encounter invalid +// UTF-8 escape sequences. +func (self *Decoder) UseUnicodeErrors() { + self.f |= 1 << _F_disable_urc +} + +// DisallowUnknownFields indicates the Decoder to return an error when the destination +// is a struct and the input contains object keys which do not match any +// non-ignored, exported fields in the destination. +func (self *Decoder) DisallowUnknownFields() { + self.f |= 1 << _F_disable_unknown +} + +// CopyString indicates the Decoder to decode string values by copying instead of referring. +func (self *Decoder) CopyString() { + self.f |= 1 << _F_copy_string +} + +// ValidateString causes the Decoder to validate string values when decoding string value +// in JSON. Validation is that, returning error when unescaped control chars(0x00-0x1f) or +// invalid UTF-8 chars in the string value of JSON. +func (self *Decoder) ValidateString() { + self.f |= 1 << _F_validate_string +} + +// Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in +// order to reduce the first-hit latency. +// +// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is +// a compile option to set the depth of recursive compile for the nested struct type. +func Pretouch(vt reflect.Type, opts ...option.CompileOption) error { + cfg := option.DefaultCompileOptions() + for _, opt := range opts { + opt(&cfg) + } + return pretouchRec(map[reflect.Type]bool{vt:true}, cfg) +} + +func pretouchType(_vt reflect.Type, opts option.CompileOptions) (map[reflect.Type]bool, error) { + /* compile function */ + compiler := newCompiler().apply(opts) + decoder := func(vt *rt.GoType, _ ...interface{}) (interface{}, error) { + if pp, err := compiler.compile(_vt); err != nil { + return nil, err + } else { + as := newAssembler(pp) + as.name = _vt.String() + return as.Load(), nil + } + } + + /* find or compile */ + vt := rt.UnpackType(_vt) + if val := programCache.Get(vt); val != nil { + return nil, nil + } else if _, err := programCache.Compute(vt, decoder); err == nil { + return compiler.rec, nil + } else { + return nil, err + } +} + +func pretouchRec(vtm map[reflect.Type]bool, opts option.CompileOptions) error { + if opts.RecursiveDepth < 0 || len(vtm) == 0 { + return nil + } + next := make(map[reflect.Type]bool) + for vt := range(vtm) { + sub, err := pretouchType(vt, opts) + if err != nil { + return err + } + for svt := range(sub) { + next[svt] = true + } + } + opts.RecursiveDepth -= 1 + return pretouchRec(next, opts) +} + +// Skip skips only one json value, and returns first non-blank character position and its ending position if it is valid. +// Otherwise, returns negative error code using start and invalid character position using end +func Skip(data []byte) (start int, end int) { + s := rt.Mem2Str(data) + p := 0 + m := types.NewStateMachine() + ret := native.SkipOne(&s, &p, m, uint64(0)) + types.FreeStateMachine(m) + return ret, p +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/errors.go b/ihub/vendor/github.com/bytedance/sonic/decoder/errors.go new file mode 100644 index 0000000..c905fdf --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/errors.go @@ -0,0 +1,181 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `encoding/json` + `errors` + `fmt` + `reflect` + `strconv` + `strings` + + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` +) + +type SyntaxError struct { + Pos int + Src string + Code types.ParsingError + Msg string +} + +func (self SyntaxError) Error() string { + return fmt.Sprintf("%q", self.Description()) +} + +func (self SyntaxError) Description() string { + return "Syntax error " + self.description() +} + +func (self SyntaxError) description() string { + i := 16 + p := self.Pos - i + q := self.Pos + i + + /* check for empty source */ + if self.Src == "" { + return fmt.Sprintf("no sources available: %#v", self) + } + + /* prevent slicing before the beginning */ + if p < 0 { + p, q, i = 0, q - p, i + p + } + + /* prevent slicing beyond the end */ + if n := len(self.Src); q > n { + n = q - n + q = len(self.Src) + + /* move the left bound if possible */ + if p > n { + i += n + p -= n + } + } + + /* left and right length */ + x := clamp_zero(i) + y := clamp_zero(q - p - i - 1) + + /* compose the error description */ + return fmt.Sprintf( + "at index %d: %s\n\n\t%s\n\t%s^%s\n", + self.Pos, + self.Message(), + self.Src[p:q], + strings.Repeat(".", x), + strings.Repeat(".", y), + ) +} + +func (self SyntaxError) Message() string { + if self.Msg == "" { + return self.Code.Message() + } + return self.Msg +} + +func clamp_zero(v int) int { + if v < 0 { + return 0 + } else { + return v + } +} + +/** JIT Error Helpers **/ + +var stackOverflow = &json.UnsupportedValueError { + Str : "Value nesting too deep", + Value : reflect.ValueOf("..."), +} + +//go:nosplit +func error_wrap(src string, pos int, code types.ParsingError) error { + return SyntaxError { + Pos : pos, + Src : src, + Code : code, + } +} + +//go:nosplit +func error_type(vt *rt.GoType) error { + return &json.UnmarshalTypeError{Type: vt.Pack()} +} + +type MismatchTypeError struct { + Pos int + Src string + Type reflect.Type +} + +func swithchJSONType (src string, pos int) string { + var val string + switch src[pos] { + case 'f': fallthrough + case 't': val = "bool" + case '"': val = "string" + case '{': val = "object" + case '[': val = "array" + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': val = "number" + } + return val +} + +func (self MismatchTypeError) Error() string { + se := SyntaxError { + Pos : self.Pos, + Src : self.Src, + Code : types.ERR_MISMATCH, + } + return fmt.Sprintf("Mismatch type %s with value %s %q", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description()) +} + +func (self MismatchTypeError) Description() string { + se := SyntaxError { + Pos : self.Pos, + Src : self.Src, + Code : types.ERR_MISMATCH, + } + return fmt.Sprintf("Mismatch type %s with value %s %s", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description()) +} + +//go:nosplit +func error_mismatch(src string, pos int, vt *rt.GoType) error { + return &MismatchTypeError { + Pos : pos, + Src : src, + Type : vt.Pack(), + } +} + +//go:nosplit +func error_field(name string) error { + return errors.New("json: unknown field " + strconv.Quote(name)) +} + +//go:nosplit +func error_value(value string, vtype reflect.Type) error { + return &json.UnmarshalTypeError { + Type : vtype, + Value : value, + } +} diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go116.go b/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go116.go new file mode 100644 index 0000000..b597043 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go116.go @@ -0,0 +1,776 @@ +// +build go1.15,!go1.17 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `encoding/json` + `fmt` + `reflect` + `strconv` + + `github.com/bytedance/sonic/internal/jit` + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/native/types` + `github.com/twitchyliquid64/golang-asm/obj` + `github.com/twitchyliquid64/golang-asm/obj/x86` +) + +/** Crucial Registers: + * + * ST(BX) : ro, decoder stack + * DF(R10) : ro, decoder flags + * EP(R11) : wo, error pointer + * IP(R12) : ro, input pointer + * IL(R13) : ro, input length + * IC(R14) : rw, input cursor + * VP(R15) : ro, value pointer (to an interface{}) + */ + +const ( + _VD_args = 8 // 8 bytes for passing arguments to this functions + _VD_fargs = 64 // 64 bytes for passing arguments to other Go functions + _VD_saves = 40 // 40 bytes for saving the registers before CALL instructions + _VD_locals = 88 // 88 bytes for local variables +) + +const ( + _VD_offs = _VD_fargs + _VD_saves + _VD_locals + _VD_size = _VD_offs + 8 // 8 bytes for the parent frame pointer +) + +var ( + _VAR_ss = _VAR_ss_Vt + _VAR_df = jit.Ptr(_SP, _VD_fargs + _VD_saves) +) + +var ( + _VAR_ss_Vt = jit.Ptr(_SP, _VD_fargs + _VD_saves + 8) + _VAR_ss_Dv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 16) + _VAR_ss_Iv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 24) + _VAR_ss_Ep = jit.Ptr(_SP, _VD_fargs + _VD_saves + 32) + _VAR_ss_Db = jit.Ptr(_SP, _VD_fargs + _VD_saves + 40) + _VAR_ss_Dc = jit.Ptr(_SP, _VD_fargs + _VD_saves + 48) +) + +var ( + _VAR_cs_LR = jit.Ptr(_SP, _VD_fargs + _VD_saves + 56) + _VAR_cs_p = jit.Ptr(_SP, _VD_fargs + _VD_saves + 64) + _VAR_cs_n = jit.Ptr(_SP, _VD_fargs + _VD_saves + 72) + _VAR_cs_d = jit.Ptr(_SP, _VD_fargs + _VD_saves + 80) +) + +type _ValueDecoder struct { + jit.BaseAssembler +} + +func (self *_ValueDecoder) build() uintptr { + self.Init(self.compile) + return *(*uintptr)(self.Load("decode_value", _VD_size, _VD_args, argPtrs_generic, localPtrs_generic)) +} + +/** Function Calling Helpers **/ + +func (self *_ValueDecoder) save(r ...obj.Addr) { + for i, v := range r { + if i > _VD_saves / 8 - 1 { + panic("too many registers to save") + } else { + self.Emit("MOVQ", v, jit.Ptr(_SP, _VD_fargs + int64(i) * 8)) + } + } +} + +func (self *_ValueDecoder) load(r ...obj.Addr) { + for i, v := range r { + if i > _VD_saves / 8 - 1 { + panic("too many registers to load") + } else { + self.Emit("MOVQ", jit.Ptr(_SP, _VD_fargs + int64(i) * 8), v) + } + } +} + +func (self *_ValueDecoder) call(fn obj.Addr) { + self.Emit("MOVQ", fn, _AX) // MOVQ ${fn}, AX + self.Rjmp("CALL", _AX) // CALL AX +} + +func (self *_ValueDecoder) call_go(fn obj.Addr) { + self.save(_REG_go...) // SAVE $REG_go + self.call(fn) // CALL ${fn} + self.load(_REG_go...) // LOAD $REG_go +} + +/** Decoder Assembler **/ + +const ( + _S_val = iota + 1 + _S_arr + _S_arr_0 + _S_obj + _S_obj_0 + _S_obj_delim + _S_obj_sep +) + +const ( + _S_omask_key = (1 << _S_obj_0) | (1 << _S_obj_sep) + _S_omask_end = (1 << _S_obj_0) | (1 << _S_obj) + _S_vmask = (1 << _S_val) | (1 << _S_arr_0) +) + +const ( + _A_init_len = 1 + _A_init_cap = 16 +) + +const ( + _ST_Sp = 0 + _ST_Vt = _PtrBytes + _ST_Vp = _PtrBytes * (types.MAX_RECURSE + 1) +) + +var ( + _V_true = jit.Imm(int64(pbool(true))) + _V_false = jit.Imm(int64(pbool(false))) + _F_value = jit.Imm(int64(native.S_value)) +) + +var ( + _V_max = jit.Imm(int64(types.V_MAX)) + _E_eof = jit.Imm(int64(types.ERR_EOF)) + _E_invalid = jit.Imm(int64(types.ERR_INVALID_CHAR)) + _E_recurse = jit.Imm(int64(types.ERR_RECURSE_EXCEED_MAX)) +) + +var ( + _F_convTslice = jit.Func(convTslice) + _F_convTstring = jit.Func(convTstring) + _F_invalid_vtype = jit.Func(invalid_vtype) +) + +var ( + _T_map = jit.Type(reflect.TypeOf((map[string]interface{})(nil))) + _T_bool = jit.Type(reflect.TypeOf(false)) + _T_int64 = jit.Type(reflect.TypeOf(int64(0))) + _T_eface = jit.Type(reflect.TypeOf((*interface{})(nil)).Elem()) + _T_slice = jit.Type(reflect.TypeOf(([]interface{})(nil))) + _T_string = jit.Type(reflect.TypeOf("")) + _T_number = jit.Type(reflect.TypeOf(json.Number(""))) + _T_float64 = jit.Type(reflect.TypeOf(float64(0))) +) + +var _R_tab = map[int]string { + '[': "_decode_V_ARRAY", + '{': "_decode_V_OBJECT", + ':': "_decode_V_KEY_SEP", + ',': "_decode_V_ELEM_SEP", + ']': "_decode_V_ARRAY_END", + '}': "_decode_V_OBJECT_END", +} + +func (self *_ValueDecoder) compile() { + self.Emit("SUBQ", jit.Imm(_VD_size), _SP) // SUBQ $_VD_size, SP + self.Emit("MOVQ", _BP, jit.Ptr(_SP, _VD_offs)) // MOVQ BP, _VD_offs(SP) + self.Emit("LEAQ", jit.Ptr(_SP, _VD_offs), _BP) // LEAQ _VD_offs(SP), BP + + /* initialize the state machine */ + self.Emit("XORL", _CX, _CX) // XORL CX, CX + self.Emit("MOVQ", _DF, _VAR_df) // MOVQ DF, df + /* initialize digital buffer first */ + self.Emit("MOVQ", jit.Imm(_MaxDigitNums), _VAR_ss_Dc) // MOVQ $_MaxDigitNums, ss.Dcap + self.Emit("LEAQ", jit.Ptr(_ST, _DbufOffset), _AX) // LEAQ _DbufOffset(ST), AX + self.Emit("MOVQ", _AX, _VAR_ss_Db) // MOVQ AX, ss.Dbuf + /* add ST offset */ + self.Emit("ADDQ", jit.Imm(_FsmOffset), _ST) // ADDQ _FsmOffset, _ST + self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp + self.WriteRecNotAX(0, _VP, jit.Ptr(_ST, _ST_Vp), false) // MOVQ VP, ST.Vp[0] + self.Emit("MOVQ", jit.Imm(_S_val), jit.Ptr(_ST, _ST_Vt)) // MOVQ _S_val, ST.Vt[0] + self.Sjmp("JMP" , "_next") // JMP _next + + /* set the value from previous round */ + self.Link("_set_value") // _set_value: + self.Emit("MOVL" , jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX + self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , "_vtype_error") // JNC _vtype_error + self.Emit("XORL" , _SI, _SI) // XORL SI, SI + self.Emit("SUBQ" , jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp + self.Emit("XCHGQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // XCHGQ ST.Vp[CX], SI + self.Emit("MOVQ" , _R8, jit.Ptr(_SI, 0)) // MOVQ R8, (SI) + self.WriteRecNotAX(1, _R9, jit.Ptr(_SI, 8), false) // MOVQ R9, 8(SI) + + /* check for value stack */ + self.Link("_next") // _next: + self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _AX) // MOVQ ST.Sp, AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , "_return") // JS _return + + /* fast path: test up to 4 characters manually */ + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + self.Emit("MOVQ" , jit.Imm(_BM_space), _DX) // MOVQ _BM_space, DX + self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' ' + self.Sjmp("JA" , "_decode_fast") // JA _decode_fast + self.Emit("BTQ" , _AX, _DX) // BTQ _AX, _DX + self.Sjmp("JNC" , "_decode_fast") // JNC _decode_fast + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + + /* at least 1 to 3 spaces */ + for i := 0; i < 3; i++ { + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' ' + self.Sjmp("JA" , "_decode_fast") // JA _decode_fast + self.Emit("BTQ" , _AX, _DX) // BTQ _AX, _DX + self.Sjmp("JNC" , "_decode_fast") // JNC _decode_fast + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + } + + /* at least 4 spaces */ + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + + /* fast path: use lookup table to select decoder */ + self.Link("_decode_fast") // _decode_fast: + self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI + self.Sref("_decode_tab", 4) // .... &_decode_tab + self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, 0), _AX) // MOVLQSX (DI)(AX*4), AX + self.Emit("TESTQ" , _AX, _AX) // TESTQ AX, AX + self.Sjmp("JZ" , "_decode_native") // JZ _decode_native + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX + self.Rjmp("JMP" , _AX) // JMP AX + + /* decode with native decoder */ + self.Link("_decode_native") // _decode_native: + self.Emit("MOVQ", _IP, _DI) // MOVQ IP, DI + self.Emit("MOVQ", _IL, _SI) // MOVQ IL, SI + self.Emit("MOVQ", _IC, _DX) // MOVQ IC, DX + self.Emit("LEAQ", _VAR_ss, _CX) // LEAQ ss, CX + self.Emit("MOVQ", _VAR_df, _R8) // MOVQ $df, R8 + self.Emit("BTSQ", jit.Imm(_F_allow_control), _R8) // ANDQ $1<<_F_allow_control, R8 + self.call(_F_value) // CALL value + self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC + + /* check for errors */ + self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , "_parsing_error") + self.Sjmp("JZ" , "_invalid_vtype") // JZ _invalid_vtype + self.Emit("CMPQ" , _AX, _V_max) // CMPQ AX, _V_max + self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype + + /* jump table selector */ + self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI + self.Sref("_switch_table", 4) // .... &_switch_table + self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, -4), _AX) // MOVLQSX -4(DI)(AX*4), AX + self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX + self.Rjmp("JMP" , _AX) // JMP AX + + /** V_EOF **/ + self.Link("_decode_V_EOF") // _decode_V_EOF: + self.Emit("MOVL", _E_eof, _EP) // MOVL _E_eof, EP + self.Sjmp("JMP" , "_error") // JMP _error + + /** V_NULL **/ + self.Link("_decode_V_NULL") // _decode_V_NULL: + self.Emit("XORL", _R8, _R8) // XORL R8, R8 + self.Emit("XORL", _R9, _R9) // XORL R9, R9 + self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI) // LEAQ -4(IC), DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /** V_TRUE **/ + self.Link("_decode_V_TRUE") // _decode_V_TRUE: + self.Emit("MOVQ", _T_bool, _R8) // MOVQ _T_bool, R8 + // TODO: maybe modified by users? + self.Emit("MOVQ", _V_true, _R9) // MOVQ _V_true, R9 + self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI) // LEAQ -4(IC), DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /** V_FALSE **/ + self.Link("_decode_V_FALSE") // _decode_V_FALSE: + self.Emit("MOVQ", _T_bool, _R8) // MOVQ _T_bool, R8 + self.Emit("MOVQ", _V_false, _R9) // MOVQ _V_false, R9 + self.Emit("LEAQ", jit.Ptr(_IC, -5), _DI) // LEAQ -5(IC), DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /** V_ARRAY **/ + self.Link("_decode_V_ARRAY") // _decode_V_ARRAY + self.Emit("MOVL", jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , "_invalid_char") // JNC _invalid_char + + /* create a new array */ + self.Emit("MOVQ", _T_eface, _AX) // MOVQ _T_eface, AX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ", jit.Imm(_A_init_len), jit.Ptr(_SP, 8)) // MOVQ _A_init_len, 8(SP) + self.Emit("MOVQ", jit.Imm(_A_init_cap), jit.Ptr(_SP, 16)) // MOVQ _A_init_cap, 16(SP) + self.call_go(_F_makeslice) // CALL_GO runtime.makeslice + self.Emit("MOVQ", jit.Ptr(_SP, 24), _DX) // MOVQ 24(SP), DX + + /* pack into an interface */ + self.Emit("MOVQ", _DX, jit.Ptr(_SP, 0)) // MOVQ DX, (SP) + self.Emit("MOVQ", jit.Imm(_A_init_len), jit.Ptr(_SP, 8)) // MOVQ _A_init_len, 8(SP) + self.Emit("MOVQ", jit.Imm(_A_init_cap), jit.Ptr(_SP, 16)) // MOVQ _A_init_cap, 16(SP) + self.call_go(_F_convTslice) // CALL_GO runtime.convTslice + self.Emit("MOVQ", jit.Ptr(_SP, 24), _R8) // MOVQ 24(SP), R8 + + /* replace current state with an array */ + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", jit.Imm(_S_arr), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_arr, ST.Vt[CX] + self.Emit("MOVQ", _T_slice, _AX) // MOVQ _T_slice, AX + self.Emit("MOVQ", _AX, jit.Ptr(_SI, 0)) // MOVQ AX, (SI) + self.WriteRecNotAX(2, _R8, jit.Ptr(_SI, 8), false) // MOVQ R8, 8(SI) + + /* add a new slot for the first element */ + self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX + self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE} + self.Sjmp("JAE" , "_stack_overflow") // JA _stack_overflow + self.Emit("MOVQ", jit.Ptr(_R8, 0), _AX) // MOVQ (R8), AX + self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp + self.WritePtrAX(3, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ AX, ST.Vp[CX] + self.Emit("MOVQ", jit.Imm(_S_arr_0), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_arr_0, ST.Vt[CX] + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_OBJECT **/ + self.Link("_decode_V_OBJECT") // _decode_V_OBJECT: + self.Emit("MOVL", jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , "_invalid_char") // JNC _invalid_char + self.call_go(_F_makemap_small) // CALL_GO runtime.makemap_small + self.Emit("MOVQ", jit.Ptr(_SP, 0), _AX) // MOVQ (SP), AX + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Imm(_S_obj_0), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_obj, ST.Vt[CX] + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", _T_map, _DX) // MOVQ _T_map, DX + self.Emit("MOVQ", _DX, jit.Ptr(_SI, 0)) // MOVQ DX, (SI) + self.WritePtrAX(4, jit.Ptr(_SI, 8), false) // MOVQ AX, 8(SI) + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_STRING **/ + self.Link("_decode_V_STRING") // _decode_V_STRING: + self.Emit("MOVQ", _VAR_ss_Iv, _CX) // MOVQ ss.Iv, CX + self.Emit("MOVQ", _IC, _AX) // MOVQ IC, AX + self.Emit("SUBQ", _CX, _AX) // SUBQ CX, AX + + /* check for escapes */ + self.Emit("CMPQ", _VAR_ss_Ep, jit.Imm(-1)) // CMPQ ss.Ep, $-1 + self.Sjmp("JNE" , "_unquote") // JNE _unquote + self.Emit("SUBQ", jit.Imm(1), _AX) // SUBQ $1, AX + self.Emit("LEAQ", jit.Sib(_IP, _CX, 1, 0), _R8) // LEAQ (IP)(CX), R8 + self.Byte(0x48, 0x8d, 0x3d) // LEAQ (PC), DI + self.Sref("_copy_string_end", 4) + self.Emit("BTQ", jit.Imm(_F_copy_string), _VAR_df) + self.Sjmp("JC", "copy_string") + self.Link("_copy_string_end") + self.Emit("XORL", _DX, _DX) // XORL DX, DX + /* strings with no escape sequences */ + self.Link("_noescape") // _noescape: + self.Emit("MOVL", jit.Imm(_S_omask_key), _DI) // MOVL _S_omask, DI + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _SI) // MOVQ ST.Vt[CX], SI + self.Emit("BTQ" , _SI, _DI) // BTQ SI, DI + self.Sjmp("JC" , "_object_key") // JC _object_key + + /* check for pre-packed strings, avoid 1 allocation */ + self.Emit("TESTQ", _DX, _DX) // TESTQ DX, DX + self.Sjmp("JNZ" , "_packed_str") // JNZ _packed_str + self.Emit("MOVQ" , _R8, jit.Ptr(_SP, 0)) // MOVQ R8, (SP) + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) + self.call_go(_F_convTstring) // CALL_GO runtime.convTstring + self.Emit("MOVQ" , jit.Ptr(_SP, 16), _R9) // MOVQ 16(SP), R9 + + /* packed string already in R9 */ + self.Link("_packed_str") // _packed_str: + self.Emit("MOVQ", _T_string, _R8) // MOVQ _T_string, R8 + self.Emit("MOVQ", _VAR_ss_Iv, _DI) // MOVQ ss.Iv, DI + self.Emit("SUBQ", jit.Imm(1), _DI) // SUBQ $1, DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /* the string is an object key, get the map */ + self.Link("_object_key") + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI + + /* add a new delimiter */ + self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX + self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE} + self.Sjmp("JAE" , "_stack_overflow") // JA _stack_overflow + self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp + self.Emit("MOVQ", jit.Imm(_S_obj_delim), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_obj_delim, ST.Vt[CX] + + /* add a new slot int the map */ + self.Emit("MOVQ", _T_map, _DX) // MOVQ _T_map, DX + self.Emit("MOVQ", _DX, jit.Ptr(_SP, 0)) // MOVQ DX, (SP) + self.Emit("MOVQ", _SI, jit.Ptr(_SP, 8)) // MOVQ SI, 8(SP) + self.Emit("MOVQ", _R8, jit.Ptr(_SP, 16)) // MOVQ R9, 16(SP) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 24)) // MOVQ AX, 24(SP) + self.call_go(_F_mapassign_faststr) // CALL_GO runtime.mapassign_faststr + self.Emit("MOVQ", jit.Ptr(_SP, 32), _AX) // MOVQ 32(SP), AX + + /* add to the pointer stack */ + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.WritePtrAX(6, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ AX, ST.Vp[CX] + self.Sjmp("JMP" , "_next") // JMP _next + + /* allocate memory to store the string header and unquoted result */ + self.Link("_unquote") // _unquote: + self.Emit("ADDQ", jit.Imm(15), _AX) // ADDQ $15, AX + self.Emit("MOVQ", _T_byte, _CX) // MOVQ _T_byte, CX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP) + self.Emit("MOVB", jit.Imm(0), jit.Ptr(_SP, 16)) // MOVB $0, 16(SP) + self.call_go(_F_mallocgc) // CALL_GO runtime.mallocgc + self.Emit("MOVQ", jit.Ptr(_SP, 24), _R9) // MOVQ 24(SP), R9 + + /* prepare the unquoting parameters */ + self.Emit("MOVQ" , _VAR_ss_Iv, _CX) // MOVQ ss.Iv, CX + self.Emit("LEAQ" , jit.Sib(_IP, _CX, 1, 0), _DI) // LEAQ (IP)(CX), DI + self.Emit("NEGQ" , _CX) // NEGQ CX + self.Emit("LEAQ" , jit.Sib(_IC, _CX, 1, -1), _SI) // LEAQ -1(IC)(CX), SI + self.Emit("LEAQ" , jit.Ptr(_R9, 16), _DX) // LEAQ 16(R8), DX + self.Emit("LEAQ" , _VAR_ss_Ep, _CX) // LEAQ ss.Ep, CX + self.Emit("XORL" , _R8, _R8) // XORL R8, R8 + self.Emit("BTQ" , jit.Imm(_F_disable_urc), _VAR_df) // BTQ ${_F_disable_urc}, fv + self.Emit("SETCC", _R8) // SETCC R8 + self.Emit("SHLQ" , jit.Imm(types.B_UNICODE_REPLACE), _R8) // SHLQ ${types.B_UNICODE_REPLACE}, R8 + + /* unquote the string, with R9 been preserved */ + self.save(_R9) // SAVE R9 + self.call(_F_unquote) // CALL unquote + self.load(_R9) // LOAD R9 + + /* check for errors */ + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , "_unquote_error") // JS _unquote_error + self.Emit("MOVL" , jit.Imm(1), _DX) // MOVL $1, DX + self.Emit("LEAQ" , jit.Ptr(_R9, 16), _R8) // ADDQ $16, R8 + self.Emit("MOVQ" , _R8, jit.Ptr(_R9, 0)) // MOVQ R8, (R9) + self.Emit("MOVQ" , _AX, jit.Ptr(_R9, 8)) // MOVQ AX, 8(R9) + self.Sjmp("JMP" , "_noescape") // JMP _noescape + + /** V_DOUBLE **/ + self.Link("_decode_V_DOUBLE") // _decode_V_DOUBLE: + self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df + self.Sjmp("JC" , "_use_number") // JC _use_number + self.Emit("MOVSD", _VAR_ss_Dv, _X0) // MOVSD ss.Dv, X0 + self.Sjmp("JMP" , "_use_float64") // JMP _use_float64 + + /** V_INTEGER **/ + self.Link("_decode_V_INTEGER") // _decode_V_INTEGER: + self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df + self.Sjmp("JC" , "_use_number") // JC _use_number + self.Emit("BTQ" , jit.Imm(_F_use_int64), _VAR_df) // BTQ _F_use_int64, df + self.Sjmp("JC" , "_use_int64") // JC _use_int64 + self.Emit("MOVQ" , _VAR_ss_Iv, _AX) // MOVQ ss.Iv, AX + self.Emit("CVTSQ2SD", _AX, _X0) // CVTSQ2SD AX, X0 + + /* represent numbers as `float64` */ + self.Link("_use_float64") // _use_float64: + self.Emit("MOVSD", _X0, jit.Ptr(_SP, 0)) // MOVSD X0, (SP) + self.call_go(_F_convT64) // CALL_GO runtime.convT64 + self.Emit("MOVQ" , _T_float64, _R8) // MOVQ _T_float64, R8 + self.Emit("MOVQ" , jit.Ptr(_SP, 8), _R9) // MOVQ 8(SP), R9 + self.Emit("MOVQ" , _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /* represent numbers as `json.Number` */ + self.Link("_use_number") // _use_number + self.Emit("MOVQ", _VAR_ss_Ep, _AX) // MOVQ ss.Ep, AX + self.Emit("LEAQ", jit.Sib(_IP, _AX, 1, 0), _SI) // LEAQ (IP)(AX), SI + self.Emit("MOVQ", _IC, _CX) // MOVQ IC, CX + self.Emit("SUBQ", _AX, _CX) // SUBQ AX, CX + self.Emit("MOVQ", _SI, jit.Ptr(_SP, 0)) // MOVQ SI, (SP) + self.Emit("MOVQ", _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP) + self.call_go(_F_convTstring) // CALL_GO runtime.convTstring + self.Emit("MOVQ", _T_number, _R8) // MOVQ _T_number, R8 + self.Emit("MOVQ", jit.Ptr(_SP, 16), _R9) // MOVQ 16(SP), R9 + self.Emit("MOVQ", _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /* represent numbers as `int64` */ + self.Link("_use_int64") // _use_int64: + self.Emit("MOVQ", _VAR_ss_Iv, _AX) // MOVQ ss.Iv, AX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.call_go(_F_convT64) // CALL_GO runtime.convT64 + self.Emit("MOVQ", _T_int64, _R8) // MOVQ _T_int64, R8 + self.Emit("MOVQ", jit.Ptr(_SP, 8), _R9) // MOVQ 8(SP), R9 + self.Emit("MOVQ", _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /** V_KEY_SEP **/ + self.Link("_decode_V_KEY_SEP") // _decode_V_KEY_SEP: + // self.Byte(0xcc) + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("CMPQ", _AX, jit.Imm(_S_obj_delim)) // CMPQ AX, _S_obj_delim + self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char + self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_val, ST.Vt[CX] + self.Emit("MOVQ", jit.Imm(_S_obj), jit.Sib(_ST, _CX, 8, _ST_Vt - 8)) // MOVQ _S_obj, ST.Vt[CX - 1] + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_ELEM_SEP **/ + self.Link("_decode_V_ELEM_SEP") // _decode_V_ELEM_SEP: + self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("CMPQ" , _AX, jit.Imm(_S_arr)) // CMPQ _AX, _S_arr + self.Sjmp("JE" , "_array_sep") // JZ _next + self.Emit("CMPQ" , _AX, jit.Imm(_S_obj)) // CMPQ _AX, _S_arr + self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char + self.Emit("MOVQ" , jit.Imm(_S_obj_sep), jit.Sib(_ST, _CX, 8, _ST_Vt)) + self.Sjmp("JMP" , "_next") // JMP _next + + /* arrays */ + self.Link("_array_sep") + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _DX) // MOVQ 8(SI), DX + self.Emit("CMPQ", _DX, jit.Ptr(_SI, 16)) // CMPQ DX, 16(SI) + self.Sjmp("JAE" , "_array_more") // JAE _array_more + + /* add a slot for the new element */ + self.Link("_array_append") // _array_append: + self.Emit("ADDQ", jit.Imm(1), jit.Ptr(_SI, 8)) // ADDQ $1, 8(SI) + self.Emit("MOVQ", jit.Ptr(_SI, 0), _SI) // MOVQ (SI), SI + self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX + self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE} + self.Sjmp("JAE" , "_stack_overflow") + self.Emit("SHLQ", jit.Imm(1), _DX) // SHLQ $1, DX + self.Emit("LEAQ", jit.Sib(_SI, _DX, 8, 0), _SI) // LEAQ (SI)(DX*8), SI + self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp + self.WriteRecNotAX(7 , _SI, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ SI, ST.Vp[CX] + self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_val, ST.Vt[CX} + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_ARRAY_END **/ + self.Link("_decode_V_ARRAY_END") // _decode_V_ARRAY_END: + self.Emit("XORL", _DX, _DX) // XORL DX, DX + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("CMPQ", _AX, jit.Imm(_S_arr_0)) // CMPQ AX, _S_arr_0 + self.Sjmp("JE" , "_first_item") // JE _first_item + self.Emit("CMPQ", _AX, jit.Imm(_S_arr)) // CMPQ AX, _S_arr + self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char + self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp + self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ DX, ST.Vp[CX] + self.Sjmp("JMP" , "_next") // JMP _next + + /* first element of an array */ + self.Link("_first_item") // _first_item: + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("SUBQ", jit.Imm(2), jit.Ptr(_ST, _ST_Sp)) // SUBQ $2, ST.Sp + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp - 8), _SI) // MOVQ ST.Vp[CX - 1], SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI + self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp - 8)) // MOVQ DX, ST.Vp[CX - 1] + self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ DX, ST.Vp[CX] + self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8)) // MOVQ DX, 8(SI) + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_OBJECT_END **/ + self.Link("_decode_V_OBJECT_END") // _decode_V_OBJECT_END: + self.Emit("MOVL", jit.Imm(_S_omask_end), _DX) // MOVL _S_omask, DI + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("BTQ" , _AX, _DX) + self.Sjmp("JNC" , "_invalid_char") // JNE _invalid_char + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp + self.Emit("MOVQ", _AX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ AX, ST.Vp[CX] + self.Sjmp("JMP" , "_next") // JMP _next + + /* return from decoder */ + self.Link("_return") // _return: + self.Emit("XORL", _EP, _EP) // XORL EP, EP + self.Emit("MOVQ", _EP, jit.Ptr(_ST, _ST_Vp)) // MOVQ EP, ST.Vp[0] + self.Link("_epilogue") // _epilogue: + self.Emit("SUBQ", jit.Imm(_FsmOffset), _ST) // SUBQ _FsmOffset, _ST + self.Emit("MOVQ", jit.Ptr(_SP, _VD_offs), _BP) // MOVQ _VD_offs(SP), BP + self.Emit("ADDQ", jit.Imm(_VD_size), _SP) // ADDQ $_VD_size, SP + self.Emit("RET") // RET + + /* array expand */ + self.Link("_array_more") // _array_more: + self.Emit("MOVQ" , _T_eface, _AX) // MOVQ _T_eface, AX + self.Emit("MOVOU", jit.Ptr(_SI, 0), _X0) // MOVOU (SI), X0 + self.Emit("MOVQ" , jit.Ptr(_SI, 16), _DX) // MOVQ 16(SI), DX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 8)) // MOVOU X0, 8(SP) + self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 24)) // MOVQ DX, 24(SP) + self.Emit("SHLQ" , jit.Imm(1), _DX) // SHLQ $1, DX + self.Emit("MOVQ" , _DX, jit.Ptr(_SP, 32)) // MOVQ DX, 32(SP) + self.call_go(_F_growslice) // CALL_GO runtime.growslice + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _DI) // MOVOU 40(SP), DI + self.Emit("MOVQ" , jit.Ptr(_SP, 48), _DX) // MOVOU 48(SP), DX + self.Emit("MOVQ" , jit.Ptr(_SP, 56), _AX) // MOVQ 56(SP), AX + + /* update the slice */ + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI + self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8)) // MOVQ DX, 8(SI) + self.Emit("MOVQ", _AX, jit.Ptr(_SI, 16)) // MOVQ AX, 16(AX) + self.WriteRecNotAX(8 , _DI, jit.Ptr(_SI, 0), false) // MOVQ R10, (SI) + self.Sjmp("JMP" , "_array_append") // JMP _array_append + + /* copy string */ + self.Link("copy_string") // pointer: R8, length: AX, return addr: DI + // self.Byte(0xcc) + self.Emit("MOVQ", _R8, _VAR_cs_p) + self.Emit("MOVQ", _AX, _VAR_cs_n) + self.Emit("MOVQ", _DI, _VAR_cs_LR) + self.Emit("MOVQ", _T_byte, jit.Ptr(_SP, 0)) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 8)) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16)) + self.call_go(_F_makeslice) + self.Emit("MOVQ", jit.Ptr(_SP, 24), _R8) + self.Emit("MOVQ", _R8, _VAR_cs_d) + self.Emit("MOVQ", _R8, jit.Ptr(_SP, 0)) + self.Emit("MOVQ", _VAR_cs_p, _R8) + self.Emit("MOVQ", _R8, jit.Ptr(_SP, 8)) + self.Emit("MOVQ", _VAR_cs_n, _AX) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16)) + self.call_go(_F_memmove) + self.Emit("MOVQ", _VAR_cs_d, _R8) + self.Emit("MOVQ", _VAR_cs_n, _AX) + self.Emit("MOVQ", _VAR_cs_LR, _DI) + // self.Byte(0xcc) + self.Rjmp("JMP", _DI) + + /* error handlers */ + self.Link("_stack_overflow") + self.Emit("MOVL" , _E_recurse, _EP) // MOVQ _E_recurse, EP + self.Sjmp("JMP" , "_error") // JMP _error + self.Link("_vtype_error") // _vtype_error: + self.Emit("MOVQ" , _DI, _IC) // MOVQ DI, IC + self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP + self.Sjmp("JMP" , "_error") // JMP _error + self.Link("_invalid_char") // _invalid_char: + self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC + self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP + self.Sjmp("JMP" , "_error") // JMP _error + self.Link("_unquote_error") // _unquote_error: + self.Emit("MOVQ" , _VAR_ss_Iv, _IC) // MOVQ ss.Iv, IC + self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC + self.Link("_parsing_error") // _parsing_error: + self.Emit("NEGQ" , _AX) // NEGQ AX + self.Emit("MOVQ" , _AX, _EP) // MOVQ AX, EP + self.Link("_error") // _error: + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_VP, 0)) // MOVOU X0, (VP) + self.Sjmp("JMP" , "_epilogue") // JMP _epilogue + + /* invalid value type, never returns */ + self.Link("_invalid_vtype") + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.call(_F_invalid_vtype) // CALL invalid_type + self.Emit("UD2") // UD2 + + /* switch jump table */ + self.Link("_switch_table") // _switch_table: + self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0 + self.Sref("_decode_V_NULL", -4) // SREF &_decode_V_NULL, $-4 + self.Sref("_decode_V_TRUE", -8) // SREF &_decode_V_TRUE, $-8 + self.Sref("_decode_V_FALSE", -12) // SREF &_decode_V_FALSE, $-12 + self.Sref("_decode_V_ARRAY", -16) // SREF &_decode_V_ARRAY, $-16 + self.Sref("_decode_V_OBJECT", -20) // SREF &_decode_V_OBJECT, $-20 + self.Sref("_decode_V_STRING", -24) // SREF &_decode_V_STRING, $-24 + self.Sref("_decode_V_DOUBLE", -28) // SREF &_decode_V_DOUBLE, $-28 + self.Sref("_decode_V_INTEGER", -32) // SREF &_decode_V_INTEGER, $-32 + self.Sref("_decode_V_KEY_SEP", -36) // SREF &_decode_V_KEY_SEP, $-36 + self.Sref("_decode_V_ELEM_SEP", -40) // SREF &_decode_V_ELEM_SEP, $-40 + self.Sref("_decode_V_ARRAY_END", -44) // SREF &_decode_V_ARRAY_END, $-44 + self.Sref("_decode_V_OBJECT_END", -48) // SREF &_decode_V_OBJECT_END, $-48 + + /* fast character lookup table */ + self.Link("_decode_tab") // _decode_tab: + self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0 + + /* generate rest of the tabs */ + for i := 1; i < 256; i++ { + if to, ok := _R_tab[i]; ok { + self.Sref(to, -int64(i) * 4) + } else { + self.Byte(0x00, 0x00, 0x00, 0x00) + } + } +} + +func (self *_ValueDecoder) WritePtrAX(i int, rec obj.Addr, saveDI bool) { + self.Emit("MOVQ", _V_writeBarrier, _R10) + self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + if saveDI { + self.save(_DI) + } + self.Emit("LEAQ", rec, _DI) + self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX + self.Rjmp("CALL", _R10) + if saveDI { + self.load(_DI) + } + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", _AX, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} + +func (self *_ValueDecoder) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool) { + if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { + panic("rec contains AX!") + } + self.Emit("MOVQ", _V_writeBarrier, _R10) + self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", ptr, _AX) + if saveDI { + self.save(_DI) + } + self.Emit("LEAQ", rec, _DI) + self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX + self.Rjmp("CALL", _R10) + if saveDI { + self.load(_DI) + } + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", ptr, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} + +/** Generic Decoder **/ + +var ( + _subr_decode_value = new(_ValueDecoder).build() +) + +//go:nosplit +func invalid_vtype(vt types.ValueType) { + throw(fmt.Sprintf("invalid value type: %d", vt)) +} diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go117.go b/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go117.go new file mode 100644 index 0000000..df1cd9f --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go117.go @@ -0,0 +1,772 @@ +//go:build go1.17 && !go1.21 +// +build go1.17,!go1.21 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `encoding/json` + `fmt` + `reflect` + `strconv` + + `github.com/bytedance/sonic/internal/jit` + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/native/types` + `github.com/twitchyliquid64/golang-asm/obj` + `github.com/twitchyliquid64/golang-asm/obj/x86` +) + +/** Crucial Registers: + * + * ST(R13) && 0(SP) : ro, decoder stack + * DF(AX) : ro, decoder flags + * EP(BX) : wo, error pointer + * IP(R10) : ro, input pointer + * IL(R12) : ro, input length + * IC(R11) : rw, input cursor + * VP(R15) : ro, value pointer (to an interface{}) + */ + +const ( + _VD_args = 8 // 8 bytes for passing arguments to this functions + _VD_fargs = 64 // 64 bytes for passing arguments to other Go functions + _VD_saves = 48 // 48 bytes for saving the registers before CALL instructions + _VD_locals = 96 // 96 bytes for local variables +) + +const ( + _VD_offs = _VD_fargs + _VD_saves + _VD_locals + _VD_size = _VD_offs + 8 // 8 bytes for the parent frame pointer +) + +var ( + _VAR_ss = _VAR_ss_Vt + _VAR_df = jit.Ptr(_SP, _VD_fargs + _VD_saves) +) + +var ( + _VAR_ss_Vt = jit.Ptr(_SP, _VD_fargs + _VD_saves + 8) + _VAR_ss_Dv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 16) + _VAR_ss_Iv = jit.Ptr(_SP, _VD_fargs + _VD_saves + 24) + _VAR_ss_Ep = jit.Ptr(_SP, _VD_fargs + _VD_saves + 32) + _VAR_ss_Db = jit.Ptr(_SP, _VD_fargs + _VD_saves + 40) + _VAR_ss_Dc = jit.Ptr(_SP, _VD_fargs + _VD_saves + 48) +) + +var ( + _VAR_R9 = jit.Ptr(_SP, _VD_fargs + _VD_saves + 56) +) +type _ValueDecoder struct { + jit.BaseAssembler +} + +var ( + _VAR_cs_LR = jit.Ptr(_SP, _VD_fargs + _VD_saves + 64) + _VAR_cs_p = jit.Ptr(_SP, _VD_fargs + _VD_saves + 72) + _VAR_cs_n = jit.Ptr(_SP, _VD_fargs + _VD_saves + 80) + _VAR_cs_d = jit.Ptr(_SP, _VD_fargs + _VD_saves + 88) +) + +func (self *_ValueDecoder) build() uintptr { + self.Init(self.compile) + return *(*uintptr)(self.Load("decode_value", _VD_size, _VD_args, argPtrs_generic, localPtrs_generic)) +} + +/** Function Calling Helpers **/ + +func (self *_ValueDecoder) save(r ...obj.Addr) { + for i, v := range r { + if i > _VD_saves / 8 - 1 { + panic("too many registers to save") + } else { + self.Emit("MOVQ", v, jit.Ptr(_SP, _VD_fargs + int64(i) * 8)) + } + } +} + +func (self *_ValueDecoder) load(r ...obj.Addr) { + for i, v := range r { + if i > _VD_saves / 8 - 1 { + panic("too many registers to load") + } else { + self.Emit("MOVQ", jit.Ptr(_SP, _VD_fargs + int64(i) * 8), v) + } + } +} + +func (self *_ValueDecoder) call(fn obj.Addr) { + self.Emit("MOVQ", fn, _R9) // MOVQ ${fn}, AX + self.Rjmp("CALL", _R9) // CALL AX +} + +func (self *_ValueDecoder) call_go(fn obj.Addr) { + self.save(_REG_go...) // SAVE $REG_go + self.call(fn) // CALL ${fn} + self.load(_REG_go...) // LOAD $REG_go +} + +func (self *_ValueDecoder) callc(fn obj.Addr) { + self.Emit("XCHGQ", _IP, _BP) + self.call(fn) + self.Emit("XCHGQ", _IP, _BP) +} + +func (self *_ValueDecoder) call_c(fn obj.Addr) { + self.Emit("XCHGQ", _IC, _BX) + self.callc(fn) + self.Emit("XCHGQ", _IC, _BX) +} + +/** Decoder Assembler **/ + +const ( + _S_val = iota + 1 + _S_arr + _S_arr_0 + _S_obj + _S_obj_0 + _S_obj_delim + _S_obj_sep +) + +const ( + _S_omask_key = (1 << _S_obj_0) | (1 << _S_obj_sep) + _S_omask_end = (1 << _S_obj_0) | (1 << _S_obj) + _S_vmask = (1 << _S_val) | (1 << _S_arr_0) +) + +const ( + _A_init_len = 1 + _A_init_cap = 16 +) + +const ( + _ST_Sp = 0 + _ST_Vt = _PtrBytes + _ST_Vp = _PtrBytes * (types.MAX_RECURSE + 1) +) + +var ( + _V_true = jit.Imm(int64(pbool(true))) + _V_false = jit.Imm(int64(pbool(false))) + _F_value = jit.Imm(int64(native.S_value)) +) + +var ( + _V_max = jit.Imm(int64(types.V_MAX)) + _E_eof = jit.Imm(int64(types.ERR_EOF)) + _E_invalid = jit.Imm(int64(types.ERR_INVALID_CHAR)) + _E_recurse = jit.Imm(int64(types.ERR_RECURSE_EXCEED_MAX)) +) + +var ( + _F_convTslice = jit.Func(convTslice) + _F_convTstring = jit.Func(convTstring) + _F_invalid_vtype = jit.Func(invalid_vtype) +) + +var ( + _T_map = jit.Type(reflect.TypeOf((map[string]interface{})(nil))) + _T_bool = jit.Type(reflect.TypeOf(false)) + _T_int64 = jit.Type(reflect.TypeOf(int64(0))) + _T_eface = jit.Type(reflect.TypeOf((*interface{})(nil)).Elem()) + _T_slice = jit.Type(reflect.TypeOf(([]interface{})(nil))) + _T_string = jit.Type(reflect.TypeOf("")) + _T_number = jit.Type(reflect.TypeOf(json.Number(""))) + _T_float64 = jit.Type(reflect.TypeOf(float64(0))) +) + +var _R_tab = map[int]string { + '[': "_decode_V_ARRAY", + '{': "_decode_V_OBJECT", + ':': "_decode_V_KEY_SEP", + ',': "_decode_V_ELEM_SEP", + ']': "_decode_V_ARRAY_END", + '}': "_decode_V_OBJECT_END", +} + +func (self *_ValueDecoder) compile() { + self.Emit("SUBQ", jit.Imm(_VD_size), _SP) // SUBQ $_VD_size, SP + self.Emit("MOVQ", _BP, jit.Ptr(_SP, _VD_offs)) // MOVQ BP, _VD_offs(SP) + self.Emit("LEAQ", jit.Ptr(_SP, _VD_offs), _BP) // LEAQ _VD_offs(SP), BP + + /* initialize the state machine */ + self.Emit("XORL", _CX, _CX) // XORL CX, CX + self.Emit("MOVQ", _DF, _VAR_df) // MOVQ DF, df + /* initialize digital buffer first */ + self.Emit("MOVQ", jit.Imm(_MaxDigitNums), _VAR_ss_Dc) // MOVQ $_MaxDigitNums, ss.Dcap + self.Emit("LEAQ", jit.Ptr(_ST, _DbufOffset), _AX) // LEAQ _DbufOffset(ST), AX + self.Emit("MOVQ", _AX, _VAR_ss_Db) // MOVQ AX, ss.Dbuf + /* add ST offset */ + self.Emit("ADDQ", jit.Imm(_FsmOffset), _ST) // ADDQ _FsmOffset, _ST + self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp + self.WriteRecNotAX(0, _VP, jit.Ptr(_ST, _ST_Vp), false) // MOVQ VP, ST.Vp[0] + self.Emit("MOVQ", jit.Imm(_S_val), jit.Ptr(_ST, _ST_Vt)) // MOVQ _S_val, ST.Vt[0] + self.Sjmp("JMP" , "_next") // JMP _next + + /* set the value from previous round */ + self.Link("_set_value") // _set_value: + self.Emit("MOVL" , jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX + self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , "_vtype_error") // JNC _vtype_error + self.Emit("XORL" , _SI, _SI) // XORL SI, SI + self.Emit("SUBQ" , jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp + self.Emit("XCHGQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // XCHGQ ST.Vp[CX], SI + self.Emit("MOVQ" , _R8, jit.Ptr(_SI, 0)) // MOVQ R8, (SI) + self.WriteRecNotAX(1, _R9, jit.Ptr(_SI, 8), false) // MOVQ R9, 8(SI) + + /* check for value stack */ + self.Link("_next") // _next: + self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _AX) // MOVQ ST.Sp, AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , "_return") // JS _return + + /* fast path: test up to 4 characters manually */ + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + self.Emit("MOVQ" , jit.Imm(_BM_space), _DX) // MOVQ _BM_space, DX + self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' ' + self.Sjmp("JA" , "_decode_fast") // JA _decode_fast + self.Emit("BTQ" , _AX, _DX) // BTQ _AX, _DX + self.Sjmp("JNC" , "_decode_fast") // JNC _decode_fast + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + + /* at least 1 to 3 spaces */ + for i := 0; i < 3; i++ { + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + self.Emit("CMPQ" , _AX, jit.Imm(' ')) // CMPQ AX, $' ' + self.Sjmp("JA" , "_decode_fast") // JA _decode_fast + self.Emit("BTQ" , _AX, _DX) // BTQ _AX, _DX + self.Sjmp("JNC" , "_decode_fast") // JNC _decode_fast + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + } + + /* at least 4 spaces */ + self.Emit("CMPQ" , _IC, _IL) // CMPQ IC, IL + self.Sjmp("JAE" , "_decode_V_EOF") // JAE _decode_V_EOF + self.Emit("MOVBQZX", jit.Sib(_IP, _IC, 1, 0), _AX) // MOVBQZX (IP)(IC), AX + + /* fast path: use lookup table to select decoder */ + self.Link("_decode_fast") // _decode_fast: + self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI + self.Sref("_decode_tab", 4) // .... &_decode_tab + self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, 0), _AX) // MOVLQSX (DI)(AX*4), AX + self.Emit("TESTQ" , _AX, _AX) // TESTQ AX, AX + self.Sjmp("JZ" , "_decode_native") // JZ _decode_native + self.Emit("ADDQ" , jit.Imm(1), _IC) // ADDQ $1, IC + self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX + self.Rjmp("JMP" , _AX) // JMP AX + + /* decode with native decoder */ + self.Link("_decode_native") // _decode_native: + self.Emit("MOVQ", _IP, _DI) // MOVQ IP, DI + self.Emit("MOVQ", _IL, _SI) // MOVQ IL, SI + self.Emit("MOVQ", _IC, _DX) // MOVQ IC, DX + self.Emit("LEAQ", _VAR_ss, _CX) // LEAQ ss, CX + self.Emit("MOVQ", _VAR_df, _R8) // MOVQ $df, R8 + self.Emit("BTSQ", jit.Imm(_F_allow_control), _R8) // ANDQ $1<<_F_allow_control, R8 + self.callc(_F_value) // CALL value + self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC + + /* check for errors */ + self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , "_parsing_error") + self.Sjmp("JZ" , "_invalid_vtype") // JZ _invalid_vtype + self.Emit("CMPQ" , _AX, _V_max) // CMPQ AX, _V_max + self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype + + /* jump table selector */ + self.Byte(0x48, 0x8d, 0x3d) // LEAQ ?(PC), DI + self.Sref("_switch_table", 4) // .... &_switch_table + self.Emit("MOVLQSX", jit.Sib(_DI, _AX, 4, -4), _AX) // MOVLQSX -4(DI)(AX*4), AX + self.Emit("ADDQ" , _DI, _AX) // ADDQ DI, AX + self.Rjmp("JMP" , _AX) // JMP AX + + /** V_EOF **/ + self.Link("_decode_V_EOF") // _decode_V_EOF: + self.Emit("MOVL", _E_eof, _EP) // MOVL _E_eof, EP + self.Sjmp("JMP" , "_error") // JMP _error + + /** V_NULL **/ + self.Link("_decode_V_NULL") // _decode_V_NULL: + self.Emit("XORL", _R8, _R8) // XORL R8, R8 + self.Emit("XORL", _R9, _R9) // XORL R9, R9 + self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI) // LEAQ -4(IC), DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /** V_TRUE **/ + self.Link("_decode_V_TRUE") // _decode_V_TRUE: + self.Emit("MOVQ", _T_bool, _R8) // MOVQ _T_bool, R8 + // TODO: maybe modified by users? + self.Emit("MOVQ", _V_true, _R9) // MOVQ _V_true, R9 + self.Emit("LEAQ", jit.Ptr(_IC, -4), _DI) // LEAQ -4(IC), DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /** V_FALSE **/ + self.Link("_decode_V_FALSE") // _decode_V_FALSE: + self.Emit("MOVQ", _T_bool, _R8) // MOVQ _T_bool, R8 + self.Emit("MOVQ", _V_false, _R9) // MOVQ _V_false, R9 + self.Emit("LEAQ", jit.Ptr(_IC, -5), _DI) // LEAQ -5(IC), DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /** V_ARRAY **/ + self.Link("_decode_V_ARRAY") // _decode_V_ARRAY + self.Emit("MOVL", jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , "_invalid_char") // JNC _invalid_char + + /* create a new array */ + self.Emit("MOVQ", _T_eface, _AX) // MOVQ _T_eface, AX + self.Emit("MOVQ", jit.Imm(_A_init_len), _BX) // MOVQ _A_init_len, BX + self.Emit("MOVQ", jit.Imm(_A_init_cap), _CX) // MOVQ _A_init_cap, CX + self.call_go(_F_makeslice) // CALL_GO runtime.makeslice + + /* pack into an interface */ + self.Emit("MOVQ", jit.Imm(_A_init_len), _BX) // MOVQ _A_init_len, BX + self.Emit("MOVQ", jit.Imm(_A_init_cap), _CX) // MOVQ _A_init_cap, CX + self.call_go(_F_convTslice) // CALL_GO runtime.convTslice + self.Emit("MOVQ", _AX, _R8) // MOVQ AX, R8 + + /* replace current state with an array */ + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", jit.Imm(_S_arr), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_arr, ST.Vt[CX] + self.Emit("MOVQ", _T_slice, _AX) // MOVQ _T_slice, AX + self.Emit("MOVQ", _AX, jit.Ptr(_SI, 0)) // MOVQ AX, (SI) + self.WriteRecNotAX(2, _R8, jit.Ptr(_SI, 8), false) // MOVQ R8, 8(SI) + + /* add a new slot for the first element */ + self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX + self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE} + self.Sjmp("JAE" , "_stack_overflow") // JA _stack_overflow + self.Emit("MOVQ", jit.Ptr(_R8, 0), _AX) // MOVQ (R8), AX + self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp + self.WritePtrAX(3, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ AX, ST.Vp[CX] + self.Emit("MOVQ", jit.Imm(_S_arr_0), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_arr_0, ST.Vt[CX] + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_OBJECT **/ + self.Link("_decode_V_OBJECT") // _decode_V_OBJECT: + self.Emit("MOVL", jit.Imm(_S_vmask), _DX) // MOVL _S_vmask, DX + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("BTQ" , _AX, _DX) // BTQ AX, DX + self.Sjmp("JNC" , "_invalid_char") // JNC _invalid_char + self.call_go(_F_makemap_small) // CALL_GO runtime.makemap_small + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Imm(_S_obj_0), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_obj_0, ST.Vt[CX] + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", _T_map, _DX) // MOVQ _T_map, DX + self.Emit("MOVQ", _DX, jit.Ptr(_SI, 0)) // MOVQ DX, (SI) + self.WritePtrAX(4, jit.Ptr(_SI, 8), false) // MOVQ AX, 8(SI) + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_STRING **/ + self.Link("_decode_V_STRING") // _decode_V_STRING: + self.Emit("MOVQ", _VAR_ss_Iv, _CX) // MOVQ ss.Iv, CX + self.Emit("MOVQ", _IC, _AX) // MOVQ IC, AX + self.Emit("SUBQ", _CX, _AX) // SUBQ CX, AX + + /* check for escapes */ + self.Emit("CMPQ", _VAR_ss_Ep, jit.Imm(-1)) // CMPQ ss.Ep, $-1 + self.Sjmp("JNE" , "_unquote") // JNE _unquote + self.Emit("SUBQ", jit.Imm(1), _AX) // SUBQ $1, AX + self.Emit("LEAQ", jit.Sib(_IP, _CX, 1, 0), _R8) // LEAQ (IP)(CX), R8 + self.Byte(0x48, 0x8d, 0x3d) // LEAQ (PC), DI + self.Sref("_copy_string_end", 4) + self.Emit("BTQ", jit.Imm(_F_copy_string), _VAR_df) + self.Sjmp("JC", "copy_string") + self.Link("_copy_string_end") + self.Emit("XORL", _DX, _DX) + + /* strings with no escape sequences */ + self.Link("_noescape") // _noescape: + self.Emit("MOVL", jit.Imm(_S_omask_key), _DI) // MOVL _S_omask, DI + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _SI) // MOVQ ST.Vt[CX], SI + self.Emit("BTQ" , _SI, _DI) // BTQ SI, DI + self.Sjmp("JC" , "_object_key") // JC _object_key + + /* check for pre-packed strings, avoid 1 allocation */ + self.Emit("TESTQ", _DX, _DX) // TESTQ DX, DX + self.Sjmp("JNZ" , "_packed_str") // JNZ _packed_str + self.Emit("MOVQ" , _AX, _BX) // MOVQ AX, BX + self.Emit("MOVQ" , _R8, _AX) // MOVQ R8, AX + self.call_go(_F_convTstring) // CALL_GO runtime.convTstring + self.Emit("MOVQ" , _AX, _R9) // MOVQ AX, R9 + + /* packed string already in R9 */ + self.Link("_packed_str") // _packed_str: + self.Emit("MOVQ", _T_string, _R8) // MOVQ _T_string, R8 + self.Emit("MOVQ", _VAR_ss_Iv, _DI) // MOVQ ss.Iv, DI + self.Emit("SUBQ", jit.Imm(1), _DI) // SUBQ $1, DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /* the string is an object key, get the map */ + self.Link("_object_key") + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI + + /* add a new delimiter */ + self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX + self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE} + self.Sjmp("JAE" , "_stack_overflow") // JA _stack_overflow + self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp + self.Emit("MOVQ", jit.Imm(_S_obj_delim), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_obj_delim, ST.Vt[CX] + + /* add a new slot int the map */ + self.Emit("MOVQ", _AX, _DI) // MOVQ AX, DI + self.Emit("MOVQ", _T_map, _AX) // MOVQ _T_map, AX + self.Emit("MOVQ", _SI, _BX) // MOVQ SI, BX + self.Emit("MOVQ", _R8, _CX) // MOVQ R9, CX + self.call_go(_F_mapassign_faststr) // CALL_GO runtime.mapassign_faststr + + /* add to the pointer stack */ + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.WritePtrAX(6, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ AX, ST.Vp[CX] + self.Sjmp("JMP" , "_next") // JMP _next + + /* allocate memory to store the string header and unquoted result */ + self.Link("_unquote") // _unquote: + self.Emit("ADDQ", jit.Imm(15), _AX) // ADDQ $15, AX + self.Emit("MOVQ", _T_byte, _BX) // MOVQ _T_byte, BX + self.Emit("MOVB", jit.Imm(0), _CX) // MOVB $0, CX + self.call_go(_F_mallocgc) // CALL_GO runtime.mallocgc + self.Emit("MOVQ", _AX, _R9) // MOVQ AX, R9 + + /* prepare the unquoting parameters */ + self.Emit("MOVQ" , _VAR_ss_Iv, _CX) // MOVQ ss.Iv, CX + self.Emit("LEAQ" , jit.Sib(_IP, _CX, 1, 0), _DI) // LEAQ (IP)(CX), DI + self.Emit("NEGQ" , _CX) // NEGQ CX + self.Emit("LEAQ" , jit.Sib(_IC, _CX, 1, -1), _SI) // LEAQ -1(IC)(CX), SI + self.Emit("LEAQ" , jit.Ptr(_R9, 16), _DX) // LEAQ 16(R8), DX + self.Emit("LEAQ" , _VAR_ss_Ep, _CX) // LEAQ ss.Ep, CX + self.Emit("XORL" , _R8, _R8) // XORL R8, R8 + self.Emit("BTQ" , jit.Imm(_F_disable_urc), _VAR_df) // BTQ ${_F_disable_urc}, fv + self.Emit("SETCC", _R8) // SETCC R8 + self.Emit("SHLQ" , jit.Imm(types.B_UNICODE_REPLACE), _R8) // SHLQ ${types.B_UNICODE_REPLACE}, R8 + + /* unquote the string, with R9 been preserved */ + self.Emit("MOVQ", _R9, _VAR_R9) // SAVE R9 + self.call_c(_F_unquote) // CALL unquote + self.Emit("MOVQ", _VAR_R9, _R9) // LOAD R9 + + /* check for errors */ + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , "_unquote_error") // JS _unquote_error + self.Emit("MOVL" , jit.Imm(1), _DX) // MOVL $1, DX + self.Emit("LEAQ" , jit.Ptr(_R9, 16), _R8) // ADDQ $16, R8 + self.Emit("MOVQ" , _R8, jit.Ptr(_R9, 0)) // MOVQ R8, (R9) + self.Emit("MOVQ" , _AX, jit.Ptr(_R9, 8)) // MOVQ AX, 8(R9) + self.Sjmp("JMP" , "_noescape") // JMP _noescape + + /** V_DOUBLE **/ + self.Link("_decode_V_DOUBLE") // _decode_V_DOUBLE: + self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df + self.Sjmp("JC" , "_use_number") // JC _use_number + self.Emit("MOVSD", _VAR_ss_Dv, _X0) // MOVSD ss.Dv, X0 + self.Sjmp("JMP" , "_use_float64") // JMP _use_float64 + + /** V_INTEGER **/ + self.Link("_decode_V_INTEGER") // _decode_V_INTEGER: + self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df + self.Sjmp("JC" , "_use_number") // JC _use_number + self.Emit("BTQ" , jit.Imm(_F_use_int64), _VAR_df) // BTQ _F_use_int64, df + self.Sjmp("JC" , "_use_int64") // JC _use_int64 + //TODO: use ss.Dv directly + self.Emit("MOVSD", _VAR_ss_Dv, _X0) // MOVSD ss.Dv, X0 + + /* represent numbers as `float64` */ + self.Link("_use_float64") // _use_float64: + self.Emit("MOVQ" , _X0, _AX) // MOVQ X0, AX + self.call_go(_F_convT64) // CALL_GO runtime.convT64 + self.Emit("MOVQ" , _T_float64, _R8) // MOVQ _T_float64, R8 + self.Emit("MOVQ" , _AX, _R9) // MOVQ AX, R9 + self.Emit("MOVQ" , _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /* represent numbers as `json.Number` */ + self.Link("_use_number") // _use_number + self.Emit("MOVQ", _VAR_ss_Ep, _AX) // MOVQ ss.Ep, AX + self.Emit("LEAQ", jit.Sib(_IP, _AX, 1, 0), _SI) // LEAQ (IP)(AX), SI + self.Emit("MOVQ", _IC, _CX) // MOVQ IC, CX + self.Emit("SUBQ", _AX, _CX) // SUBQ AX, CX + self.Emit("MOVQ", _SI, _AX) // MOVQ SI, AX + self.Emit("MOVQ", _CX, _BX) // MOVQ CX, BX + self.call_go(_F_convTstring) // CALL_GO runtime.convTstring + self.Emit("MOVQ", _T_number, _R8) // MOVQ _T_number, R8 + self.Emit("MOVQ", _AX, _R9) // MOVQ AX, R9 + self.Emit("MOVQ", _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /* represent numbers as `int64` */ + self.Link("_use_int64") // _use_int64: + self.Emit("MOVQ", _VAR_ss_Iv, _AX) // MOVQ ss.Iv, AX + self.call_go(_F_convT64) // CALL_GO runtime.convT64 + self.Emit("MOVQ", _T_int64, _R8) // MOVQ _T_int64, R8 + self.Emit("MOVQ", _AX, _R9) // MOVQ AX, R9 + self.Emit("MOVQ", _VAR_ss_Ep, _DI) // MOVQ ss.Ep, DI + self.Sjmp("JMP" , "_set_value") // JMP _set_value + + /** V_KEY_SEP **/ + self.Link("_decode_V_KEY_SEP") // _decode_V_KEY_SEP: + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("CMPQ", _AX, jit.Imm(_S_obj_delim)) // CMPQ AX, _S_obj_delim + self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char + self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_val, ST.Vt[CX] + self.Emit("MOVQ", jit.Imm(_S_obj), jit.Sib(_ST, _CX, 8, _ST_Vt - 8)) // MOVQ _S_obj, ST.Vt[CX - 1] + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_ELEM_SEP **/ + self.Link("_decode_V_ELEM_SEP") // _decode_V_ELEM_SEP: + self.Emit("MOVQ" , jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ" , jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("CMPQ" , _AX, jit.Imm(_S_arr)) + self.Sjmp("JE" , "_array_sep") // JZ _next + self.Emit("CMPQ" , _AX, jit.Imm(_S_obj)) // CMPQ _AX, _S_arr + self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char + self.Emit("MOVQ" , jit.Imm(_S_obj_sep), jit.Sib(_ST, _CX, 8, _ST_Vt)) + self.Sjmp("JMP" , "_next") // JMP _next + + /* arrays */ + self.Link("_array_sep") + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _DX) // MOVQ 8(SI), DX + self.Emit("CMPQ", _DX, jit.Ptr(_SI, 16)) // CMPQ DX, 16(SI) + self.Sjmp("JAE" , "_array_more") // JAE _array_more + + /* add a slot for the new element */ + self.Link("_array_append") // _array_append: + self.Emit("ADDQ", jit.Imm(1), jit.Ptr(_SI, 8)) // ADDQ $1, 8(SI) + self.Emit("MOVQ", jit.Ptr(_SI, 0), _SI) // MOVQ (SI), SI + self.Emit("ADDQ", jit.Imm(1), _CX) // ADDQ $1, CX + self.Emit("CMPQ", _CX, jit.Imm(types.MAX_RECURSE)) // CMPQ CX, ${types.MAX_RECURSE} + self.Sjmp("JAE" , "_stack_overflow") // JA _stack_overflow + self.Emit("SHLQ", jit.Imm(1), _DX) // SHLQ $1, DX + self.Emit("LEAQ", jit.Sib(_SI, _DX, 8, 0), _SI) // LEAQ (SI)(DX*8), SI + self.Emit("MOVQ", _CX, jit.Ptr(_ST, _ST_Sp)) // MOVQ CX, ST.Sp + self.WriteRecNotAX(7 , _SI, jit.Sib(_ST, _CX, 8, _ST_Vp), false) // MOVQ SI, ST.Vp[CX] + self.Emit("MOVQ", jit.Imm(_S_val), jit.Sib(_ST, _CX, 8, _ST_Vt)) // MOVQ _S_val, ST.Vt[CX} + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_ARRAY_END **/ + self.Link("_decode_V_ARRAY_END") // _decode_V_ARRAY_END: + self.Emit("XORL", _DX, _DX) // XORL DX, DX + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("CMPQ", _AX, jit.Imm(_S_arr_0)) // CMPQ AX, _S_arr_0 + self.Sjmp("JE" , "_first_item") // JE _first_item + self.Emit("CMPQ", _AX, jit.Imm(_S_arr)) // CMPQ AX, _S_arr + self.Sjmp("JNE" , "_invalid_char") // JNE _invalid_char + self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp + self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ DX, ST.Vp[CX] + self.Sjmp("JMP" , "_next") // JMP _next + + /* first element of an array */ + self.Link("_first_item") // _first_item: + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("SUBQ", jit.Imm(2), jit.Ptr(_ST, _ST_Sp)) // SUBQ $2, ST.Sp + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp - 8), _SI) // MOVQ ST.Vp[CX - 1], SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI + self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp - 8)) // MOVQ DX, ST.Vp[CX - 1] + self.Emit("MOVQ", _DX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ DX, ST.Vp[CX] + self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8)) // MOVQ DX, 8(SI) + self.Sjmp("JMP" , "_next") // JMP _next + + /** V_OBJECT_END **/ + self.Link("_decode_V_OBJECT_END") // _decode_V_OBJECT_END: + self.Emit("MOVL", jit.Imm(_S_omask_end), _DI) // MOVL _S_omask, DI + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vt), _AX) // MOVQ ST.Vt[CX], AX + self.Emit("BTQ" , _AX, _DI) + self.Sjmp("JNC" , "_invalid_char") // JNE _invalid_char + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("SUBQ", jit.Imm(1), jit.Ptr(_ST, _ST_Sp)) // SUBQ $1, ST.Sp + self.Emit("MOVQ", _AX, jit.Sib(_ST, _CX, 8, _ST_Vp)) // MOVQ AX, ST.Vp[CX] + self.Sjmp("JMP" , "_next") // JMP _next + + /* return from decoder */ + self.Link("_return") // _return: + self.Emit("XORL", _EP, _EP) // XORL EP, EP + self.Emit("MOVQ", _EP, jit.Ptr(_ST, _ST_Vp)) // MOVQ EP, ST.Vp[0] + self.Link("_epilogue") // _epilogue: + self.Emit("SUBQ", jit.Imm(_FsmOffset), _ST) // SUBQ _FsmOffset, _ST + self.Emit("MOVQ", jit.Ptr(_SP, _VD_offs), _BP) // MOVQ _VD_offs(SP), BP + self.Emit("ADDQ", jit.Imm(_VD_size), _SP) // ADDQ $_VD_size, SP + self.Emit("RET") // RET + + /* array expand */ + self.Link("_array_more") // _array_more: + self.Emit("MOVQ" , _T_eface, _AX) // MOVQ _T_eface, AX + self.Emit("MOVQ" , jit.Ptr(_SI, 0), _BX) // MOVQ (SI), BX + self.Emit("MOVQ" , jit.Ptr(_SI, 8), _CX) // MOVQ 8(SI), CX + self.Emit("MOVQ" , jit.Ptr(_SI, 16), _DI) // MOVQ 16(SI), DI + self.Emit("MOVQ" , _DI, _SI) // MOVQ DI, 24(SP) + self.Emit("SHLQ" , jit.Imm(1), _SI) // SHLQ $1, SI + self.call_go(_F_growslice) // CALL_GO runtime.growslice + self.Emit("MOVQ" , _AX, _DI) // MOVQ AX, DI + self.Emit("MOVQ" , _BX, _DX) // MOVQ BX, DX + self.Emit("MOVQ" , _CX, _AX) // MOVQ CX, AX + + /* update the slice */ + self.Emit("MOVQ", jit.Ptr(_ST, _ST_Sp), _CX) // MOVQ ST.Sp, CX + self.Emit("MOVQ", jit.Sib(_ST, _CX, 8, _ST_Vp), _SI) // MOVQ ST.Vp[CX], SI + self.Emit("MOVQ", jit.Ptr(_SI, 8), _SI) // MOVQ 8(SI), SI + self.Emit("MOVQ", _DX, jit.Ptr(_SI, 8)) // MOVQ DX, 8(SI) + self.Emit("MOVQ", _AX, jit.Ptr(_SI, 16)) // MOVQ AX, 16(AX) + self.WriteRecNotAX(8 , _DI, jit.Ptr(_SI, 0), false) // MOVQ R10, (SI) + self.Sjmp("JMP" , "_array_append") // JMP _array_append + + /* copy string */ + self.Link("copy_string") // pointer: R8, length: AX, return addr: DI + self.Emit("MOVQ", _R8, _VAR_cs_p) + self.Emit("MOVQ", _AX, _VAR_cs_n) + self.Emit("MOVQ", _DI, _VAR_cs_LR) + self.Emit("MOVQ", _AX, _BX) + self.Emit("MOVQ", _AX, _CX) + self.Emit("MOVQ", _T_byte, _AX) + self.call_go(_F_makeslice) + self.Emit("MOVQ", _AX, _VAR_cs_d) + self.Emit("MOVQ", _VAR_cs_p, _BX) + self.Emit("MOVQ", _VAR_cs_n, _CX) + self.call_go(_F_memmove) + self.Emit("MOVQ", _VAR_cs_d, _R8) + self.Emit("MOVQ", _VAR_cs_n, _AX) + self.Emit("MOVQ", _VAR_cs_LR, _DI) + self.Rjmp("JMP", _DI) + + /* error handlers */ + self.Link("_stack_overflow") + self.Emit("MOVL" , _E_recurse, _EP) // MOVQ _E_recurse, EP + self.Sjmp("JMP" , "_error") // JMP _error + self.Link("_vtype_error") // _vtype_error: + self.Emit("MOVQ" , _DI, _IC) // MOVQ DI, IC + self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP + self.Sjmp("JMP" , "_error") // JMP _error + self.Link("_invalid_char") // _invalid_char: + self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC + self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP + self.Sjmp("JMP" , "_error") // JMP _error + self.Link("_unquote_error") // _unquote_error: + self.Emit("MOVQ" , _VAR_ss_Iv, _IC) // MOVQ ss.Iv, IC + self.Emit("SUBQ" , jit.Imm(1), _IC) // SUBQ $1, IC + self.Link("_parsing_error") // _parsing_error: + self.Emit("NEGQ" , _AX) // NEGQ AX + self.Emit("MOVQ" , _AX, _EP) // MOVQ AX, EP + self.Link("_error") // _error: + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Ptr(_VP, 0)) // MOVOU X0, (VP) + self.Sjmp("JMP" , "_epilogue") // JMP _epilogue + + /* invalid value type, never returns */ + self.Link("_invalid_vtype") + self.call_go(_F_invalid_vtype) // CALL invalid_type + self.Emit("UD2") // UD2 + + /* switch jump table */ + self.Link("_switch_table") // _switch_table: + self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0 + self.Sref("_decode_V_NULL", -4) // SREF &_decode_V_NULL, $-4 + self.Sref("_decode_V_TRUE", -8) // SREF &_decode_V_TRUE, $-8 + self.Sref("_decode_V_FALSE", -12) // SREF &_decode_V_FALSE, $-12 + self.Sref("_decode_V_ARRAY", -16) // SREF &_decode_V_ARRAY, $-16 + self.Sref("_decode_V_OBJECT", -20) // SREF &_decode_V_OBJECT, $-20 + self.Sref("_decode_V_STRING", -24) // SREF &_decode_V_STRING, $-24 + self.Sref("_decode_V_DOUBLE", -28) // SREF &_decode_V_DOUBLE, $-28 + self.Sref("_decode_V_INTEGER", -32) // SREF &_decode_V_INTEGER, $-32 + self.Sref("_decode_V_KEY_SEP", -36) // SREF &_decode_V_KEY_SEP, $-36 + self.Sref("_decode_V_ELEM_SEP", -40) // SREF &_decode_V_ELEM_SEP, $-40 + self.Sref("_decode_V_ARRAY_END", -44) // SREF &_decode_V_ARRAY_END, $-44 + self.Sref("_decode_V_OBJECT_END", -48) // SREF &_decode_V_OBJECT_END, $-48 + + /* fast character lookup table */ + self.Link("_decode_tab") // _decode_tab: + self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0 + + /* generate rest of the tabs */ + for i := 1; i < 256; i++ { + if to, ok := _R_tab[i]; ok { + self.Sref(to, -int64(i) * 4) + } else { + self.Byte(0x00, 0x00, 0x00, 0x00) + } + } +} + +func (self *_ValueDecoder) WritePtrAX(i int, rec obj.Addr, saveDI bool) { + self.Emit("MOVQ", _V_writeBarrier, _R9) + self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + if saveDI { + self.save(_DI) + } + self.Emit("LEAQ", rec, _DI) + self.call(_F_gcWriteBarrierAX) + if saveDI { + self.load(_DI) + } + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", _AX, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} + +func (self *_ValueDecoder) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool) { + if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { + panic("rec contains AX!") + } + self.Emit("MOVQ", _V_writeBarrier, _AX) + self.Emit("CMPL", jit.Ptr(_AX, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", ptr, _AX) + if saveDI { + self.save(_DI) + } + self.Emit("LEAQ", rec, _DI) + self.call(_F_gcWriteBarrierAX) + if saveDI { + self.load(_DI) + } + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", ptr, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} + +/** Generic Decoder **/ + +var ( + _subr_decode_value = new(_ValueDecoder).build() +) + +//go:nosplit +func invalid_vtype(vt types.ValueType) { + throw(fmt.Sprintf("invalid value type: %d", vt)) +} diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go117_test.s b/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go117_test.s new file mode 100644 index 0000000..6c2686d --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_go117_test.s @@ -0,0 +1,37 @@ +// +build go1.17,!go1.21 + +// +// Copyright 2021 ByteDance Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "go_asm.h" +#include "funcdata.h" +#include "textflag.h" + +TEXT ·decodeValueStub(SB), NOSPLIT, $0 - 72 + NO_LOCAL_POINTERS + PXOR X0, X0 + MOVOU X0, rv+48(FP) + MOVQ st+0(FP) , R13 + MOVQ sp+8(FP) , R10 + MOVQ sn+16(FP), R12 + MOVQ ic+24(FP), R11 + MOVQ vp+32(FP), R15 + MOVQ df+40(FP), AX + MOVQ ·_subr_decode_value(SB), BX + CALL BX + MOVQ R11, rp+48(FP) + MOVQ BX, ex+56(FP) + RET diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_test.s b/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_test.s new file mode 100644 index 0000000..36cb1f5 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/generic_amd64_test.s @@ -0,0 +1,37 @@ +// +build go1.15,!go1.17 + +// +// Copyright 2021 ByteDance Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "go_asm.h" +#include "funcdata.h" +#include "textflag.h" + +TEXT ·decodeValueStub(SB), NOSPLIT, $0 - 72 + NO_LOCAL_POINTERS + PXOR X0, X0 + MOVOU X0, rv+48(FP) + MOVQ st+0(FP), BX + MOVQ sp+8(FP), R12 + MOVQ sn+16(FP), R13 + MOVQ ic+24(FP), R14 + MOVQ vp+32(FP), R15 + MOVQ df+40(FP), R10 + MOVQ ·_subr_decode_value(SB), AX + CALL AX + MOVQ R14, rp+48(FP) + MOVQ R11, ex+56(FP) + RET diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/pools.go b/ihub/vendor/github.com/bytedance/sonic/decoder/pools.go new file mode 100644 index 0000000..ab1e5f2 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/pools.go @@ -0,0 +1,143 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `sync` + `unsafe` + + `github.com/bytedance/sonic/internal/caching` + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` +) + +const ( + _MinSlice = 16 + _MaxStack = 4096 // 4k slots + _MaxStackBytes = _MaxStack * _PtrBytes + _MaxDigitNums = 800 // used in atof fallback algorithm +) + +const ( + _PtrBytes = _PTR_SIZE / 8 + _FsmOffset = (_MaxStack + 1) * _PtrBytes + _DbufOffset = _FsmOffset + int64(unsafe.Sizeof(types.StateMachine{})) + types.MAX_RECURSE * _PtrBytes + _StackSize = unsafe.Sizeof(_Stack{}) +) + +var ( + stackPool = sync.Pool{} + valueCache = []unsafe.Pointer(nil) + fieldCache = []*caching.FieldMap(nil) + fieldCacheMux = sync.Mutex{} + programCache = caching.CreateProgramCache() +) + +type _Stack struct { + sp uintptr + sb [_MaxStack]unsafe.Pointer + mm types.StateMachine + vp [types.MAX_RECURSE]unsafe.Pointer + dp [_MaxDigitNums]byte +} + +type _Decoder func( + s string, + i int, + 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 +) (int, error) + +var _KeepAlive struct { + s string + i int + vp unsafe.Pointer + sb *_Stack + fv uint64 + sv string + vk unsafe.Pointer + + ret int + err error + + frame_decoder [_FP_offs]byte + frame_generic [_VD_offs]byte +} + +var ( + argPtrs = []bool{true, false, false, true, true, false, true, false, true} + localPtrs = []bool{} +) + +var ( + argPtrs_generic = []bool{true} + localPtrs_generic = []bool{} +) + +func newStack() *_Stack { + if ret := stackPool.Get(); ret == nil { + return new(_Stack) + } else { + return ret.(*_Stack) + } +} + +func resetStack(p *_Stack) { + memclrNoHeapPointers(unsafe.Pointer(p), _StackSize) +} + +func freeStack(p *_Stack) { + p.sp = 0 + stackPool.Put(p) +} + +func freezeValue(v unsafe.Pointer) uintptr { + valueCache = append(valueCache, v) + return uintptr(v) +} + +func freezeFields(v *caching.FieldMap) int64 { + fieldCacheMux.Lock() + fieldCache = append(fieldCache, v) + fieldCacheMux.Unlock() + return referenceFields(v) +} + +func referenceFields(v *caching.FieldMap) int64 { + return int64(uintptr(unsafe.Pointer(v))) +} + +func makeDecoder(vt *rt.GoType, _ ...interface{}) (interface{}, error) { + if pp, err := newCompiler().compile(vt.Pack()); err != nil { + return nil, err + } else { + return newAssembler(pp).Load(), nil + } +} + +func findOrCompile(vt *rt.GoType) (_Decoder, error) { + if val := programCache.Get(vt); val != nil { + return val.(_Decoder), nil + } else if ret, err := programCache.Compute(vt, makeDecoder); err == nil { + return ret.(_Decoder), nil + } else { + return nil, err + } +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/primitives.go b/ihub/vendor/github.com/bytedance/sonic/decoder/primitives.go new file mode 100644 index 0000000..d6053e2 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/primitives.go @@ -0,0 +1,46 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `encoding` + `encoding/json` + `unsafe` + + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/rt` +) + +func decodeTypedPointer(s string, i int, vt *rt.GoType, vp unsafe.Pointer, sb *_Stack, fv uint64) (int, error) { + if fn, err := findOrCompile(vt); err != nil { + return 0, err + } else { + rt.MoreStack(_FP_size + _VD_size + native.MaxFrameSize) + rt.StopProf() + ret, err := fn(s, i, vp, sb, fv, "", nil) + rt.StartProf() + return ret, err + } +} + +func decodeJsonUnmarshaler(vv interface{}, s string) error { + return vv.(json.Unmarshaler).UnmarshalJSON(rt.Str2Mem(s)) +} + +func decodeTextUnmarshaler(vv interface{}, s string) error { + return vv.(encoding.TextUnmarshaler).UnmarshalText(rt.Str2Mem(s)) +} diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/stream.go b/ihub/vendor/github.com/bytedance/sonic/decoder/stream.go new file mode 100644 index 0000000..06dc818 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/stream.go @@ -0,0 +1,217 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `bytes` + `io` + `sync` + + `github.com/bytedance/sonic/internal/native/types` +) + +var ( + defaultBufferSize uint = 4096 + growSliceFactorShift uint = 1 + minLeftBufferShift uint = 2 +) + +type StreamDecoder struct { + r io.Reader + buf []byte + scanp int + scanned int64 + err error + Decoder +} + +var bufPool = sync.Pool{ + New: func () interface{} { + return make([]byte, 0, defaultBufferSize) + }, +} + +// NewStreamDecoder adapts to encoding/json.NewDecoder API. +// +// NewStreamDecoder returns a new decoder that reads from r. +func NewStreamDecoder(r io.Reader) *StreamDecoder { + return &StreamDecoder{r : r} +} + +// Decode decodes input stream into val with corresponding data. +// Redundantly bytes may be read and left in its buffer, and can be used at next call. +// Either io error from underlying io.Reader (except io.EOF) +// or syntax error from data will be recorded and stop subsequently decoding. +func (self *StreamDecoder) Decode(val interface{}) (err error) { + if self.err != nil { + return self.err + } + + var buf = self.buf[self.scanp:] + var p = 0 + var recycle bool + if cap(buf) == 0 { + buf = bufPool.Get().([]byte) + recycle = true + } + + var first = true + var repeat = true +read_more: + for { + l := len(buf) + realloc(&buf) + n, err := self.r.Read(buf[l:cap(buf)]) + buf = buf[:l+n] + if err != nil { + repeat = false + if err == io.EOF { + if len(buf) == 0 { + return err + } + break + } + self.err = err + return err + } + if n > 0 || first { + break + } + } + first = false + + l := len(buf) + if l > 0 { + self.Decoder.Reset(string(buf)) + err = self.Decoder.Decode(val) + if err != nil { + if repeat && self.repeatable(err) { + goto read_more + } + self.err = err + } + + p = self.Decoder.Pos() + self.scanned += int64(p) + self.scanp = 0 + } + + if l > p { + // remain undecoded bytes, so copy them into self.buf + self.buf = append(self.buf[:0], buf[p:]...) + } else { + self.buf = nil + recycle = true + } + + if recycle { + buf = buf[:0] + bufPool.Put(buf) + } + return err +} + +func (self StreamDecoder) repeatable(err error) bool { + if ee, ok := err.(SyntaxError); ok && + (ee.Code == types.ERR_EOF || (ee.Code == types.ERR_INVALID_CHAR && self.i >= len(self.s)-1)) { + return true + } + return false +} + +// InputOffset returns the input stream byte offset of the current decoder position. +// The offset gives the location of the end of the most recently returned token and the beginning of the next token. +func (self *StreamDecoder) InputOffset() int64 { + return self.scanned + int64(self.scanp) +} + +// Buffered returns a reader of the data remaining in the Decoder's buffer. +// The reader is valid until the next call to Decode. +func (self *StreamDecoder) Buffered() io.Reader { + return bytes.NewReader(self.buf[self.scanp:]) +} + +// More reports whether there is another element in the +// current array or object being parsed. +func (self *StreamDecoder) More() bool { + if self.err != nil { + return false + } + c, err := self.peek() + return err == nil && c != ']' && c != '}' +} + +func (self *StreamDecoder) peek() (byte, error) { + var err error + for { + for i := self.scanp; i < len(self.buf); i++ { + c := self.buf[i] + if isSpace(c) { + continue + } + self.scanp = i + return c, nil + } + // buffer has been scanned, now report any error + if err != nil { + if err != io.EOF { + self.err = err + } + return 0, err + } + err = self.refill() + } +} + +func isSpace(c byte) bool { + return types.SPACE_MASK & (1 << c) != 0 +} + +func (self *StreamDecoder) refill() error { + // Make room to read more into the buffer. + // First slide down data already consumed. + if self.scanp > 0 { + self.scanned += int64(self.scanp) + n := copy(self.buf, self.buf[self.scanp:]) + self.buf = self.buf[:n] + self.scanp = 0 + } + + // Grow buffer if not large enough. + realloc(&self.buf) + + // Read. Delay error for next iteration (after scan). + n, err := self.r.Read(self.buf[len(self.buf):cap(self.buf)]) + self.buf = self.buf[0 : len(self.buf)+n] + + return err +} + +func realloc(buf *[]byte) { + l := uint(len(*buf)) + c := uint(cap(*buf)) + if c - l <= c >> minLeftBufferShift { + e := l+(l>>minLeftBufferShift) + if e < defaultBufferSize { + e = defaultBufferSize + } + tmp := make([]byte, l, e) + copy(tmp, *buf) + *buf = tmp + } +} + diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/stubs_go115.go b/ihub/vendor/github.com/bytedance/sonic/decoder/stubs_go115.go new file mode 100644 index 0000000..1a0917c --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/stubs_go115.go @@ -0,0 +1,111 @@ +// +build go1.15,!go1.20 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `unsafe` + `reflect` + + _ `github.com/chenzhuoyu/base64x` + + `github.com/bytedance/sonic/internal/rt` +) + +//go:linkname _subr__b64decode github.com/chenzhuoyu/base64x._subr__b64decode +var _subr__b64decode uintptr + +// runtime.maxElementSize +const _max_map_element_size uintptr = 128 + +func mapfast(vt reflect.Type) bool { + return vt.Elem().Size() <= _max_map_element_size +} + +//go:nosplit +//go:linkname throw runtime.throw +//goland:noinspection GoUnusedParameter +func throw(s string) + +//go:linkname convT64 runtime.convT64 +//goland:noinspection GoUnusedParameter +func convT64(v uint64) unsafe.Pointer + +//go:linkname convTslice runtime.convTslice +//goland:noinspection GoUnusedParameter +func convTslice(v []byte) unsafe.Pointer + +//go:linkname convTstring runtime.convTstring +//goland:noinspection GoUnusedParameter +func convTstring(v string) unsafe.Pointer + +//go:noescape +//go:linkname memequal runtime.memequal +//goland:noinspection GoUnusedParameter +func memequal(a unsafe.Pointer, b unsafe.Pointer, size uintptr) bool + +//go:noescape +//go:linkname memmove runtime.memmove +//goland:noinspection GoUnusedParameter +func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr) + +//go:linkname mallocgc runtime.mallocgc +//goland:noinspection GoUnusedParameter +func mallocgc(size uintptr, typ *rt.GoType, needzero bool) unsafe.Pointer + +//go:linkname makeslice runtime.makeslice +//goland:noinspection GoUnusedParameter +func makeslice(et *rt.GoType, len int, cap int) unsafe.Pointer + +//go:noescape +//go:linkname growslice runtime.growslice +//goland:noinspection GoUnusedParameter +func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice + +//go:linkname makemap_small runtime.makemap_small +func makemap_small() unsafe.Pointer + +//go:linkname mapassign runtime.mapassign +//goland:noinspection GoUnusedParameter +func mapassign(t *rt.GoType, h unsafe.Pointer, k unsafe.Pointer) unsafe.Pointer + +//go:linkname mapassign_fast32 runtime.mapassign_fast32 +//goland:noinspection GoUnusedParameter +func mapassign_fast32(t *rt.GoType, h unsafe.Pointer, k uint32) unsafe.Pointer + +//go:linkname mapassign_fast64 runtime.mapassign_fast64 +//goland:noinspection GoUnusedParameter +func mapassign_fast64(t *rt.GoType, h unsafe.Pointer, k uint64) unsafe.Pointer + +//go:linkname mapassign_fast64ptr runtime.mapassign_fast64ptr +//goland:noinspection GoUnusedParameter +func mapassign_fast64ptr(t *rt.GoType, h unsafe.Pointer, k unsafe.Pointer) unsafe.Pointer + +//go:linkname mapassign_faststr runtime.mapassign_faststr +//goland:noinspection GoUnusedParameter +func mapassign_faststr(t *rt.GoType, h unsafe.Pointer, s string) unsafe.Pointer + +//go:nosplit +//go:linkname memclrHasPointers runtime.memclrHasPointers +//goland:noinspection GoUnusedParameter +func memclrHasPointers(ptr unsafe.Pointer, n uintptr) + +//go:noescape +//go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers +//goland:noinspection GoUnusedParameter +func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/stubs_go120.go b/ihub/vendor/github.com/bytedance/sonic/decoder/stubs_go120.go new file mode 100644 index 0000000..cde6a19 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/stubs_go120.go @@ -0,0 +1,111 @@ +// +build go1.20 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `unsafe` + `reflect` + + _ `github.com/chenzhuoyu/base64x` + + `github.com/bytedance/sonic/internal/rt` +) + +//go:linkname _subr__b64decode github.com/chenzhuoyu/base64x._subr__b64decode +var _subr__b64decode uintptr + +// runtime.maxElementSize +const _max_map_element_size uintptr = 128 + +func mapfast(vt reflect.Type) bool { + return vt.Elem().Size() <= _max_map_element_size +} + +//go:nosplit +//go:linkname throw runtime.throw +//goland:noinspection GoUnusedParameter +func throw(s string) + +//go:linkname convT64 runtime.convT64 +//goland:noinspection GoUnusedParameter +func convT64(v uint64) unsafe.Pointer + +//go:linkname convTslice runtime.convTslice +//goland:noinspection GoUnusedParameter +func convTslice(v []byte) unsafe.Pointer + +//go:linkname convTstring runtime.convTstring +//goland:noinspection GoUnusedParameter +func convTstring(v string) unsafe.Pointer + +//go:noescape +//go:linkname memequal runtime.memequal +//goland:noinspection GoUnusedParameter +func memequal(a unsafe.Pointer, b unsafe.Pointer, size uintptr) bool + +//go:noescape +//go:linkname memmove runtime.memmove +//goland:noinspection GoUnusedParameter +func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr) + +//go:linkname mallocgc runtime.mallocgc +//goland:noinspection GoUnusedParameter +func mallocgc(size uintptr, typ *rt.GoType, needzero bool) unsafe.Pointer + +//go:linkname makeslice runtime.makeslice +//goland:noinspection GoUnusedParameter +func makeslice(et *rt.GoType, len int, cap int) unsafe.Pointer + +//go:noescape +//go:linkname growslice reflect.growslice +//goland:noinspection GoUnusedParameter +func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice + +//go:linkname makemap_small runtime.makemap_small +func makemap_small() unsafe.Pointer + +//go:linkname mapassign runtime.mapassign +//goland:noinspection GoUnusedParameter +func mapassign(t *rt.GoType, h unsafe.Pointer, k unsafe.Pointer) unsafe.Pointer + +//go:linkname mapassign_fast32 runtime.mapassign_fast32 +//goland:noinspection GoUnusedParameter +func mapassign_fast32(t *rt.GoType, h unsafe.Pointer, k uint32) unsafe.Pointer + +//go:linkname mapassign_fast64 runtime.mapassign_fast64 +//goland:noinspection GoUnusedParameter +func mapassign_fast64(t *rt.GoType, h unsafe.Pointer, k uint64) unsafe.Pointer + +//go:linkname mapassign_fast64ptr runtime.mapassign_fast64ptr +//goland:noinspection GoUnusedParameter +func mapassign_fast64ptr(t *rt.GoType, h unsafe.Pointer, k unsafe.Pointer) unsafe.Pointer + +//go:linkname mapassign_faststr runtime.mapassign_faststr +//goland:noinspection GoUnusedParameter +func mapassign_faststr(t *rt.GoType, h unsafe.Pointer, s string) unsafe.Pointer + +//go:nosplit +//go:linkname memclrHasPointers runtime.memclrHasPointers +//goland:noinspection GoUnusedParameter +func memclrHasPointers(ptr unsafe.Pointer, n uintptr) + +//go:noescape +//go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers +//goland:noinspection GoUnusedParameter +func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/types.go b/ihub/vendor/github.com/bytedance/sonic/decoder/types.go new file mode 100644 index 0000000..6fc0e70 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/types.go @@ -0,0 +1,58 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `encoding` + `encoding/base64` + `encoding/json` + `reflect` + `unsafe` + + `github.com/bytedance/sonic/internal/rt` +) + +var ( + byteType = reflect.TypeOf(byte(0)) + intType = reflect.TypeOf(int(0)) + int8Type = reflect.TypeOf(int8(0)) + int16Type = reflect.TypeOf(int16(0)) + int32Type = reflect.TypeOf(int32(0)) + int64Type = reflect.TypeOf(int64(0)) + uintType = reflect.TypeOf(uint(0)) + uint8Type = reflect.TypeOf(uint8(0)) + uint16Type = reflect.TypeOf(uint16(0)) + uint32Type = reflect.TypeOf(uint32(0)) + uint64Type = reflect.TypeOf(uint64(0)) + float32Type = reflect.TypeOf(float32(0)) + float64Type = reflect.TypeOf(float64(0)) + stringType = reflect.TypeOf("") + bytesType = reflect.TypeOf([]byte(nil)) + jsonNumberType = reflect.TypeOf(json.Number("")) + base64CorruptInputError = reflect.TypeOf(base64.CorruptInputError(0)) +) + +var ( + errorType = reflect.TypeOf((*error)(nil)).Elem() + jsonUnmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() + encodingTextUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +) + +func rtype(t reflect.Type) (*rt.GoItab, *rt.GoType) { + p := (*rt.GoIface)(unsafe.Pointer(&t)) + return p.Itab, (*rt.GoType)(p.Value) +} diff --git a/ihub/vendor/github.com/bytedance/sonic/decoder/utils.go b/ihub/vendor/github.com/bytedance/sonic/decoder/utils.go new file mode 100644 index 0000000..23ee5d5 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/decoder/utils.go @@ -0,0 +1,39 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package decoder + +import ( + `unsafe` + + `github.com/bytedance/sonic/loader` +) + +//go:nosplit +func pbool(v bool) uintptr { + return freezeValue(unsafe.Pointer(&v)) +} + +//go:nosplit +func ptodec(p loader.Function) _Decoder { + return *(*_Decoder)(unsafe.Pointer(&p)) +} + +func assert_eq(v int64, exp int64, msg string) { + if v != exp { + panic(msg) + } +} diff --git a/ihub/vendor/github.com/bytedance/sonic/encoder/asm.s b/ihub/vendor/github.com/bytedance/sonic/encoder/asm.s new file mode 100644 index 0000000..e69de29 diff --git a/ihub/vendor/github.com/bytedance/sonic/encoder/assembler_amd64_go116.go b/ihub/vendor/github.com/bytedance/sonic/encoder/assembler_amd64_go116.go new file mode 100644 index 0000000..9b59784 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/encoder/assembler_amd64_go116.go @@ -0,0 +1,1198 @@ +// +build go1.15,!go1.17 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package encoder + +import ( + `fmt` + `reflect` + `strconv` + `unsafe` + + `github.com/bytedance/sonic/internal/cpu` + `github.com/bytedance/sonic/internal/jit` + `github.com/bytedance/sonic/internal/native/types` + `github.com/twitchyliquid64/golang-asm/obj` + `github.com/twitchyliquid64/golang-asm/obj/x86` + + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/rt` +) + +/** Register Allocations + * + * State Registers: + * + * %rbx : stack base + * %rdi : result pointer + * %rsi : result length + * %rdx : result capacity + * %r12 : sp->p + * %r13 : sp->q + * %r14 : sp->x + * %r15 : sp->f + * + * Error Registers: + * + * %r10 : error type register + * %r11 : error pointer register + */ + +/** Function Prototype & Stack Map + * + * func (buf *[]byte, p unsafe.Pointer, sb *_Stack, fv uint64) (err error) + * + * buf : (FP) + * p : 8(FP) + * sb : 16(FP) + * fv : 24(FP) + * err.vt : 32(FP) + * err.vp : 40(FP) + */ + +const ( + _S_cond = iota + _S_init +) + +const ( + _FP_args = 48 // 48 bytes for passing arguments to this function + _FP_fargs = 64 // 64 bytes for passing arguments to other Go functions + _FP_saves = 64 // 64 bytes for saving the registers before CALL instructions + _FP_locals = 24 // 24 bytes for local variables +) + +const ( + _FP_offs = _FP_fargs + _FP_saves + _FP_locals + _FP_size = _FP_offs + 8 // 8 bytes for the parent frame pointer + _FP_base = _FP_size + 8 // 8 bytes for the return address +) + +const ( + _FM_exp32 = 0x7f800000 + _FM_exp64 = 0x7ff0000000000000 +) + +const ( + _IM_null = 0x6c6c756e // 'null' + _IM_true = 0x65757274 // 'true' + _IM_fals = 0x736c6166 // 'fals' ('false' without the 'e') + _IM_open = 0x00225c22 // '"\"∅' + _IM_array = 0x5d5b // '[]' + _IM_object = 0x7d7b // '{}' + _IM_mulv = -0x5555555555555555 +) + +const ( + _LB_more_space = "_more_space" + _LB_more_space_return = "_more_space_return_" +) + +const ( + _LB_error = "_error" + _LB_error_too_deep = "_error_too_deep" + _LB_error_invalid_number = "_error_invalid_number" + _LB_error_nan_or_infinite = "_error_nan_or_infinite" + _LB_panic = "_panic" +) + +var ( + _AX = jit.Reg("AX") + _CX = jit.Reg("CX") + _DX = jit.Reg("DX") + _DI = jit.Reg("DI") + _SI = jit.Reg("SI") + _BP = jit.Reg("BP") + _SP = jit.Reg("SP") + _R8 = jit.Reg("R8") +) + +var ( + _X0 = jit.Reg("X0") + _Y0 = jit.Reg("Y0") +) + +var ( + _ST = jit.Reg("BX") + _RP = jit.Reg("DI") + _RL = jit.Reg("SI") + _RC = jit.Reg("DX") +) + +var ( + _LR = jit.Reg("R9") + _R10 = jit.Reg("R10") // used for gcWriterBarrier + _ET = jit.Reg("R10") + _EP = jit.Reg("R11") +) + +var ( + _SP_p = jit.Reg("R12") + _SP_q = jit.Reg("R13") + _SP_x = jit.Reg("R14") + _SP_f = jit.Reg("R15") +) + +var ( + _ARG_rb = jit.Ptr(_SP, _FP_base) + _ARG_vp = jit.Ptr(_SP, _FP_base + 8) + _ARG_sb = jit.Ptr(_SP, _FP_base + 16) + _ARG_fv = jit.Ptr(_SP, _FP_base + 24) +) + +var ( + _RET_et = jit.Ptr(_SP, _FP_base + 32) + _RET_ep = jit.Ptr(_SP, _FP_base + 40) +) + +var ( + _VAR_sp = jit.Ptr(_SP, _FP_fargs + _FP_saves) + _VAR_dn = jit.Ptr(_SP, _FP_fargs + _FP_saves + 8) + _VAR_vp = jit.Ptr(_SP, _FP_fargs + _FP_saves + 16) +) + +var ( + _REG_ffi = []obj.Addr{_RP, _RL, _RC} + _REG_enc = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _RL} + _REG_jsr = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _LR} + _REG_all = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _RP, _RL, _RC} +) + +type _Assembler struct { + jit.BaseAssembler + p _Program + x int + name string +} + +func newAssembler(p _Program) *_Assembler { + return new(_Assembler).Init(p) +} + +/** Assembler Interface **/ +func (self *_Assembler) Load() _Encoder { + return ptoenc(self.BaseAssembler.Load("encode_"+self.name, _FP_size, _FP_args, argPtrs, localPtrs)) +} + +func (self *_Assembler) Init(p _Program) *_Assembler { + self.p = p + self.BaseAssembler.Init(self.compile) + return self +} + +func (self *_Assembler) compile() { + self.prologue() + self.instrs() + self.epilogue() + self.builtins() +} + +/** Assembler Stages **/ + +var _OpFuncTab = [256]func(*_Assembler, *_Instr) { + _OP_null : (*_Assembler)._asm_OP_null, + _OP_empty_arr : (*_Assembler)._asm_OP_empty_arr, + _OP_empty_obj : (*_Assembler)._asm_OP_empty_obj, + _OP_bool : (*_Assembler)._asm_OP_bool, + _OP_i8 : (*_Assembler)._asm_OP_i8, + _OP_i16 : (*_Assembler)._asm_OP_i16, + _OP_i32 : (*_Assembler)._asm_OP_i32, + _OP_i64 : (*_Assembler)._asm_OP_i64, + _OP_u8 : (*_Assembler)._asm_OP_u8, + _OP_u16 : (*_Assembler)._asm_OP_u16, + _OP_u32 : (*_Assembler)._asm_OP_u32, + _OP_u64 : (*_Assembler)._asm_OP_u64, + _OP_f32 : (*_Assembler)._asm_OP_f32, + _OP_f64 : (*_Assembler)._asm_OP_f64, + _OP_str : (*_Assembler)._asm_OP_str, + _OP_bin : (*_Assembler)._asm_OP_bin, + _OP_quote : (*_Assembler)._asm_OP_quote, + _OP_number : (*_Assembler)._asm_OP_number, + _OP_eface : (*_Assembler)._asm_OP_eface, + _OP_iface : (*_Assembler)._asm_OP_iface, + _OP_byte : (*_Assembler)._asm_OP_byte, + _OP_text : (*_Assembler)._asm_OP_text, + _OP_deref : (*_Assembler)._asm_OP_deref, + _OP_index : (*_Assembler)._asm_OP_index, + _OP_load : (*_Assembler)._asm_OP_load, + _OP_save : (*_Assembler)._asm_OP_save, + _OP_drop : (*_Assembler)._asm_OP_drop, + _OP_drop_2 : (*_Assembler)._asm_OP_drop_2, + _OP_recurse : (*_Assembler)._asm_OP_recurse, + _OP_is_nil : (*_Assembler)._asm_OP_is_nil, + _OP_is_nil_p1 : (*_Assembler)._asm_OP_is_nil_p1, + _OP_is_zero_1 : (*_Assembler)._asm_OP_is_zero_1, + _OP_is_zero_2 : (*_Assembler)._asm_OP_is_zero_2, + _OP_is_zero_4 : (*_Assembler)._asm_OP_is_zero_4, + _OP_is_zero_8 : (*_Assembler)._asm_OP_is_zero_8, + _OP_is_zero_map : (*_Assembler)._asm_OP_is_zero_map, + _OP_goto : (*_Assembler)._asm_OP_goto, + _OP_map_iter : (*_Assembler)._asm_OP_map_iter, + _OP_map_stop : (*_Assembler)._asm_OP_map_stop, + _OP_map_check_key : (*_Assembler)._asm_OP_map_check_key, + _OP_map_write_key : (*_Assembler)._asm_OP_map_write_key, + _OP_map_value_next : (*_Assembler)._asm_OP_map_value_next, + _OP_slice_len : (*_Assembler)._asm_OP_slice_len, + _OP_slice_next : (*_Assembler)._asm_OP_slice_next, + _OP_marshal : (*_Assembler)._asm_OP_marshal, + _OP_marshal_p : (*_Assembler)._asm_OP_marshal_p, + _OP_marshal_text : (*_Assembler)._asm_OP_marshal_text, + _OP_marshal_text_p : (*_Assembler)._asm_OP_marshal_text_p, + _OP_cond_set : (*_Assembler)._asm_OP_cond_set, + _OP_cond_testc : (*_Assembler)._asm_OP_cond_testc, +} + +func (self *_Assembler) instr(v *_Instr) { + if fn := _OpFuncTab[v.op()]; fn != nil { + fn(self, v) + } else { + panic(fmt.Sprintf("invalid opcode: %d", v.op())) + } +} + +func (self *_Assembler) instrs() { + for i, v := range self.p { + self.Mark(i) + self.instr(&v) + self.debug_instr(i, &v) + } +} + +func (self *_Assembler) builtins() { + self.more_space() + self.error_too_deep() + self.error_invalid_number() + self.error_nan_or_infinite() + self.go_panic() +} + +func (self *_Assembler) epilogue() { + self.Mark(len(self.p)) + self.Emit("XORL", _ET, _ET) + self.Emit("XORL", _EP, _EP) + self.Link(_LB_error) + self.Emit("MOVQ", _ARG_rb, _AX) // MOVQ rb<>+0(FP), AX + self.Emit("MOVQ", _RL, jit.Ptr(_AX, 8)) // MOVQ RL, 8(AX) + self.Emit("MOVQ", _ET, _RET_et) // MOVQ ET, et<>+24(FP) + self.Emit("MOVQ", _EP, _RET_ep) // MOVQ EP, ep<>+32(FP) + self.Emit("MOVQ", jit.Ptr(_SP, _FP_offs), _BP) // MOVQ _FP_offs(SP), BP + self.Emit("ADDQ", jit.Imm(_FP_size), _SP) // ADDQ $_FP_size, SP + self.Emit("RET") // RET +} + +func (self *_Assembler) prologue() { + self.Emit("SUBQ", jit.Imm(_FP_size), _SP) // SUBQ $_FP_size, SP + self.Emit("MOVQ", _BP, jit.Ptr(_SP, _FP_offs)) // MOVQ BP, _FP_offs(SP) + self.Emit("LEAQ", jit.Ptr(_SP, _FP_offs), _BP) // LEAQ _FP_offs(SP), BP + self.load_buffer() // LOAD {buf} + self.Emit("MOVQ", _ARG_vp, _SP_p) // MOVQ vp<>+8(FP), SP.p + self.Emit("MOVQ", _ARG_sb, _ST) // MOVQ sb<>+16(FP), ST + self.Emit("XORL", _SP_x, _SP_x) // XORL SP.x, SP.x + self.Emit("XORL", _SP_f, _SP_f) // XORL SP.f, SP.f + self.Emit("XORL", _SP_q, _SP_q) // XORL SP.q, SP.q +} + +/** Assembler Inline Functions **/ + +func (self *_Assembler) xsave(reg ...obj.Addr) { + for i, v := range reg { + if i > _FP_saves / 8 - 1 { + panic("too many registers to save") + } else { + self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs + int64(i) * 8)) + } + } +} + +func (self *_Assembler) xload(reg ...obj.Addr) { + for i, v := range reg { + if i > _FP_saves / 8 - 1 { + panic("too many registers to load") + } else { + self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs + int64(i) * 8), v) + } + } +} + +func (self *_Assembler) rbuf_di() { + if _RP.Reg != x86.REG_DI { + panic("register allocation messed up: RP != DI") + } else { + self.Emit("ADDQ", _RL, _RP) + } +} + +func (self *_Assembler) store_int(nd int, fn obj.Addr, ins string) { + self.check_size(nd) + self.save_c() // SAVE $C_regs + self.rbuf_di() // MOVQ RP, DI + self.Emit(ins, jit.Ptr(_SP_p, 0), _SI) // $ins (SP.p), SI + self.call_c(fn) // CALL_C $fn + self.Emit("ADDQ", _AX, _RL) // ADDQ AX, RL +} + +func (self *_Assembler) store_str(s string) { + i := 0 + m := rt.Str2Mem(s) + + /* 8-byte stores */ + for i <= len(m) - 8 { + self.Emit("MOVQ", jit.Imm(rt.Get64(m[i:])), _AX) // MOVQ $s[i:], AX + self.Emit("MOVQ", _AX, jit.Sib(_RP, _RL, 1, int64(i))) // MOVQ AX, i(RP)(RL) + i += 8 + } + + /* 4-byte stores */ + if i <= len(m) - 4 { + self.Emit("MOVL", jit.Imm(int64(rt.Get32(m[i:]))), jit.Sib(_RP, _RL, 1, int64(i))) // MOVL $s[i:], i(RP)(RL) + i += 4 + } + + /* 2-byte stores */ + if i <= len(m) - 2 { + self.Emit("MOVW", jit.Imm(int64(rt.Get16(m[i:]))), jit.Sib(_RP, _RL, 1, int64(i))) // MOVW $s[i:], i(RP)(RL) + i += 2 + } + + /* last byte */ + if i < len(m) { + self.Emit("MOVB", jit.Imm(int64(m[i])), jit.Sib(_RP, _RL, 1, int64(i))) // MOVB $s[i:], i(RP)(RL) + } +} + +func (self *_Assembler) check_size(n int) { + self.check_size_rl(jit.Ptr(_RL, int64(n))) +} + +func (self *_Assembler) check_size_r(r obj.Addr, d int) { + self.check_size_rl(jit.Sib(_RL, r, 1, int64(d))) +} + +func (self *_Assembler) check_size_rl(v obj.Addr) { + idx := self.x + key := _LB_more_space_return + strconv.Itoa(idx) + + /* the following code relies on LR == R9 to work */ + if _LR.Reg != x86.REG_R9 { + panic("register allocation messed up: LR != R9") + } + + /* check for buffer capacity */ + self.x++ + self.Emit("LEAQ", v, _AX) // LEAQ $v, AX + self.Emit("CMPQ", _AX, _RC) // CMPQ AX, RC + self.Sjmp("JBE" , key) // JBE _more_space_return_{n} + self.slice_grow_ax(key) // GROW $key + self.Link(key) // _more_space_return_{n}: +} + +func (self *_Assembler) slice_grow_ax(ret string) { + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ ?(PC), R9 + self.Sref(ret, 4) // .... &ret + self.Sjmp("JMP" , _LB_more_space) // JMP _more_space +} + +/** State Stack Helpers **/ + +const ( + _StateSize = int64(unsafe.Sizeof(_State{})) + _StackLimit = _MaxStack * _StateSize +) + +func (self *_Assembler) save_state() { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _CX) // MOVQ (ST), CX + self.Emit("LEAQ", jit.Ptr(_CX, _StateSize), _R8) // LEAQ _StateSize(CX), R8 + self.Emit("CMPQ", _R8, jit.Imm(_StackLimit)) // CMPQ R8, $_StackLimit + self.Sjmp("JAE" , _LB_error_too_deep) // JA _error_too_deep + self.Emit("MOVQ", _SP_x, jit.Sib(_ST, _CX, 1, 8)) // MOVQ SP.x, 8(ST)(CX) + self.Emit("MOVQ", _SP_f, jit.Sib(_ST, _CX, 1, 16)) // MOVQ SP.f, 16(ST)(CX) + self.WriteRecNotAX(0, _SP_p, jit.Sib(_ST, _CX, 1, 24)) // MOVQ SP.p, 24(ST)(CX) + self.WriteRecNotAX(1, _SP_q, jit.Sib(_ST, _CX, 1, 32)) // MOVQ SP.q, 32(ST)(CX) + self.Emit("MOVQ", _R8, jit.Ptr(_ST, 0)) // MOVQ R8, (ST) +} + +func (self *_Assembler) drop_state(decr int64) { + self.Emit("MOVQ" , jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("SUBQ" , jit.Imm(decr), _AX) // SUBQ $decr, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_ST, 0)) // MOVQ AX, (ST) + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 8), _SP_x) // MOVQ 8(ST)(AX), SP.x + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 16), _SP_f) // MOVQ 16(ST)(AX), SP.f + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 24), _SP_p) // MOVQ 24(ST)(AX), SP.p + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 32), _SP_q) // MOVQ 32(ST)(AX), SP.q + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 8)) // MOVOU X0, 8(ST)(AX) + self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 24)) // MOVOU X0, 24(ST)(AX) +} + +/** Buffer Helpers **/ + +func (self *_Assembler) add_char(ch byte) { + self.Emit("MOVB", jit.Imm(int64(ch)), jit.Sib(_RP, _RL, 1, 0)) // MOVB $ch, (RP)(RL) + self.Emit("ADDQ", jit.Imm(1), _RL) // ADDQ $1, RL +} + +func (self *_Assembler) add_long(ch uint32, n int64) { + self.Emit("MOVL", jit.Imm(int64(ch)), jit.Sib(_RP, _RL, 1, 0)) // MOVL $ch, (RP)(RL) + self.Emit("ADDQ", jit.Imm(n), _RL) // ADDQ $n, RL +} + +func (self *_Assembler) add_text(ss string) { + self.store_str(ss) // TEXT $ss + self.Emit("ADDQ", jit.Imm(int64(len(ss))), _RL) // ADDQ ${len(ss)}, RL +} + +func (self *_Assembler) prep_buffer() { + self.Emit("MOVQ", _ARG_rb, _AX) // MOVQ rb<>+0(FP), AX + self.Emit("MOVQ", _RL, jit.Ptr(_AX, 8)) // MOVQ RL, 8(AX) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) +} + +func (self *_Assembler) prep_buffer_c() { + self.Emit("MOVQ", _ARG_rb, _DI) // MOVQ rb<>+0(FP), DI + self.Emit("MOVQ", _RL, jit.Ptr(_DI, 8)) // MOVQ RL, 8(DI) +} + +func (self *_Assembler) save_buffer() { + self.Emit("MOVQ", _ARG_rb, _CX) // MOVQ rb<>+0(FP), CX + self.Emit("MOVQ", _RP, jit.Ptr(_CX, 0)) // MOVQ RP, (CX) + self.Emit("MOVQ", _RL, jit.Ptr(_CX, 8)) // MOVQ RL, 8(CX) + self.Emit("MOVQ", _RC, jit.Ptr(_CX, 16)) // MOVQ RC, 16(CX) +} + +func (self *_Assembler) load_buffer() { + self.Emit("MOVQ", _ARG_rb, _AX) // MOVQ rb<>+0(FP), AX + self.Emit("MOVQ", jit.Ptr(_AX, 0), _RP) // MOVQ (AX), RP + self.Emit("MOVQ", jit.Ptr(_AX, 8), _RL) // MOVQ 8(AX), RL + self.Emit("MOVQ", jit.Ptr(_AX, 16), _RC) // MOVQ 16(AX), RC +} + +/** Function Interface Helpers **/ + +func (self *_Assembler) call(pc obj.Addr) { + self.Emit("MOVQ", pc, _AX) // MOVQ $pc, AX + self.Rjmp("CALL", _AX) // CALL AX +} + +func (self *_Assembler) save_c() { + self.xsave(_REG_ffi...) // SAVE $REG_ffi +} + +func (self *_Assembler) call_c(pc obj.Addr) { + self.call(pc) // CALL $pc + self.xload(_REG_ffi...) // LOAD $REG_ffi +} + +func (self *_Assembler) call_go(pc obj.Addr) { + self.xsave(_REG_all...) // SAVE $REG_all + self.call(pc) // CALL $pc + self.xload(_REG_all...) // LOAD $REG_all +} + +func (self *_Assembler) call_encoder(pc obj.Addr) { + self.xsave(_REG_enc...) // SAVE $REG_enc + self.call(pc) // CALL $pc + self.xload(_REG_enc...) // LOAD $REG_enc + self.load_buffer() // LOAD {buf} +} + +func (self *_Assembler) call_marshaler(fn obj.Addr, it *rt.GoType, vt reflect.Type) { + switch vt.Kind() { + case reflect.Interface : self.call_marshaler_i(fn, it) + case reflect.Ptr, reflect.Map: self.call_marshaler_v(fn, it, vt, true) + default : self.call_marshaler_v(fn, it, vt, false) + } +} + +func (self *_Assembler) call_marshaler_i(fn obj.Addr, it *rt.GoType) { + self.Emit("MOVQ" , jit.Gtype(it), _AX) // MOVQ $it, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _CX) // MOVQ 8(SP.p), CX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JZ" , "_null_{n}") // JZ _null_{n} + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) + self.Emit("MOVQ" , _CX, jit.Ptr(_SP, 16)) // MOVQ CX, 16(SP) + self.call_go(_F_assertI2I) // CALL_GO assertI2I + self.prep_buffer() // MOVE {buf}, (SP) + self.Emit("MOVOU", jit.Ptr(_SP, 24), _X0) // MOVOU 24(SP), X0 + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 8)) // MOVOU X0, 8(SP) + self.Emit("MOVQ", _ARG_fv, _CX) // MOVQ ARG.fv, CX + self.Emit("MOVQ", _CX, jit.Ptr(_SP, 24)) // MOVQ CX, 24(SP) + self.call_encoder(fn) // CALL $fn + self.Emit("MOVQ" , jit.Ptr(_SP, 32), _ET) // MOVQ 32(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _EP) // MOVQ 40(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error + self.Sjmp("JMP" , "_done_{n}") // JMP _done_{n} + self.Link("_null_{n}") // _null_{n}: + self.check_size(4) // SIZE $4 + self.Emit("MOVL", jit.Imm(_IM_null), jit.Sib(_RP, _RL, 1, 0)) // MOVL $'null', (RP)(RL*1) + self.Emit("ADDQ", jit.Imm(4), _RL) // ADDQ $4, RL + self.Link("_done_{n}") // _done_{n}: +} + +func (self *_Assembler) call_marshaler_v(fn obj.Addr, it *rt.GoType, vt reflect.Type, deref bool) { + self.prep_buffer() // MOVE {buf}, (SP) + self.Emit("MOVQ", jit.Itab(it, vt), _AX) // MOVQ $(itab(it, vt)), AX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) + + /* dereference the pointer if needed */ + if !deref { + self.Emit("MOVQ", _SP_p, jit.Ptr(_SP, 16)) // MOVQ SP.p, 16(SP) + } else { + self.Emit("MOVQ", jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 16)) // MOVQ AX, 16(SP) + } + + /* call the encoder, and perform error checks */ + self.Emit("MOVQ", _ARG_fv, _CX) // MOVQ ARG.fv, CX + self.Emit("MOVQ", _CX, jit.Ptr(_SP, 24)) // MOVQ CX, 24(SP) + self.call_encoder(fn) // CALL $fn + self.Emit("MOVQ" , jit.Ptr(_SP, 32), _ET) // MOVQ 32(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _EP) // MOVQ 40(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error +} + +/** Builtin: _more_space **/ + +var ( + _T_byte = jit.Type(byteType) + _F_growslice = jit.Func(growslice) +) + +func (self *_Assembler) more_space() { + self.Link(_LB_more_space) + self.Emit("MOVQ", _T_byte, jit.Ptr(_SP, 0)) // MOVQ $_T_byte, (SP) + self.Emit("MOVQ", _RP, jit.Ptr(_SP, 8)) // MOVQ RP, 8(SP) + self.Emit("MOVQ", _RL, jit.Ptr(_SP, 16)) // MOVQ RL, 16(SP) + self.Emit("MOVQ", _RC, jit.Ptr(_SP, 24)) // MOVQ RC, 24(SP) + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 32)) // MOVQ AX, 32(SP) + self.xsave(_REG_jsr...) // SAVE $REG_jsr + self.call(_F_growslice) // CALL $pc + self.xload(_REG_jsr...) // LOAD $REG_jsr + self.Emit("MOVQ", jit.Ptr(_SP, 40), _RP) // MOVQ 40(SP), RP + self.Emit("MOVQ", jit.Ptr(_SP, 48), _RL) // MOVQ 48(SP), RL + self.Emit("MOVQ", jit.Ptr(_SP, 56), _RC) // MOVQ 56(SP), RC + self.save_buffer() // SAVE {buf} + self.Rjmp("JMP" , _LR) // JMP LR +} + +/** Builtin Errors **/ + +var ( + _V_ERR_too_deep = jit.Imm(int64(uintptr(unsafe.Pointer(_ERR_too_deep)))) + _V_ERR_nan_or_infinite = jit.Imm(int64(uintptr(unsafe.Pointer(_ERR_nan_or_infinite)))) + _I_json_UnsupportedValueError = jit.Itab(rt.UnpackType(errorType), jsonUnsupportedValueType) +) + +func (self *_Assembler) error_too_deep() { + self.Link(_LB_error_too_deep) + self.Emit("MOVQ", _V_ERR_too_deep, _EP) // MOVQ $_V_ERR_too_deep, EP + self.Emit("MOVQ", _I_json_UnsupportedValueError, _ET) // MOVQ $_I_json_UnsupportedValuError, ET + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) error_invalid_number() { + self.Link(_LB_error_invalid_number) + self.call_go(_F_error_number) // CALL_GO error_number + self.Emit("MOVQ", jit.Ptr(_SP, 16), _ET) // MOVQ 16(SP), ET + self.Emit("MOVQ", jit.Ptr(_SP, 24), _EP) // MOVQ 24(SP), EP + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) error_nan_or_infinite() { + self.Link(_LB_error_nan_or_infinite) + self.Emit("MOVQ", _V_ERR_nan_or_infinite, _EP) // MOVQ $_V_ERR_nan_or_infinite, EP + self.Emit("MOVQ", _I_json_UnsupportedValueError, _ET) // MOVQ $_I_json_UnsupportedValuError, ET + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +/** String Encoding Routine **/ + +var ( + _F_quote = jit.Imm(int64(native.S_quote)) + _F_panic = jit.Func(goPanic) +) + +func (self *_Assembler) go_panic() { + self.Link(_LB_panic) + self.Emit("MOVQ", _SP_p, jit.Ptr(_SP, 8)) + self.call_go(_F_panic) +} + +func (self *_Assembler) encode_string(doubleQuote bool) { + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _AX) // MOVQ 8(SP.p), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JZ" , "_str_empty_{n}") // JZ _str_empty_{n} + self.Emit("CMPQ", jit.Ptr(_SP_p, 0), jit.Imm(0)) + self.Sjmp("JNE" , "_str_next_{n}") + self.Emit("MOVQ", jit.Imm(int64(panicNilPointerOfNonEmptyString)), jit.Ptr(_SP, 0)) + self.Sjmp("JMP", _LB_panic) + self.Link("_str_next_{n}") + + /* openning quote, check for double quote */ + if !doubleQuote { + self.check_size_r(_AX, 2) // SIZE $2 + self.add_char('"') // CHAR $'"' + } else { + self.check_size_r(_AX, 6) // SIZE $6 + self.add_long(_IM_open, 3) // TEXT $`"\"` + } + + /* quoting loop */ + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("MOVQ", _AX, _VAR_sp) // MOVQ AX, sp + self.Link("_str_loop_{n}") // _str_loop_{n}: + self.save_c() // SAVE $REG_ffi + + /* load the output buffer first, and then input buffer, + * because the parameter registers collide with RP / RL / RC */ + self.Emit("MOVQ", _RC, _CX) // MOVQ RC, CX + self.Emit("SUBQ", _RL, _CX) // SUBQ RL, CX + self.Emit("MOVQ", _CX, _VAR_dn) // MOVQ CX, dn + self.Emit("LEAQ", jit.Sib(_RP, _RL, 1, 0), _DX) // LEAQ (RP)(RL), DX + self.Emit("LEAQ", _VAR_dn, _CX) // LEAQ dn, CX + self.Emit("MOVQ", _VAR_sp, _AX) // MOVQ sp, AX + self.Emit("MOVQ", jit.Ptr(_SP_p, 0), _DI) // MOVQ (SP.p), DI + self.Emit("MOVQ", jit.Ptr(_SP_p, 8), _SI) // MOVQ 8(SP.p), SI + self.Emit("ADDQ", _AX, _DI) // ADDQ AX, DI + self.Emit("SUBQ", _AX, _SI) // SUBQ AX, SI + + /* set the flags based on `doubleQuote` */ + if !doubleQuote { + self.Emit("XORL", _R8, _R8) // XORL R8, R8 + } else { + self.Emit("MOVL", jit.Imm(types.F_DOUBLE_UNQUOTE), _R8) // MOVL ${types.F_DOUBLE_UNQUOTE}, R8 + } + + /* call the native quoter */ + self.call_c(_F_quote) // CALL quote + self.Emit("ADDQ" , _VAR_dn, _RL) // ADDQ dn, RL + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , "_str_space_{n}") // JS _str_space_{n} + + /* close the string, check for double quote */ + if !doubleQuote { + self.check_size(1) // SIZE $1 + self.add_char('"') // CHAR $'"' + self.Sjmp("JMP", "_str_end_{n}") // JMP _str_end_{n} + } else { + self.check_size(3) // SIZE $3 + self.add_text("\\\"\"") // TEXT $'\""' + self.Sjmp("JMP", "_str_end_{n}") // JMP _str_end_{n} + } + + /* not enough space to contain the quoted string */ + self.Link("_str_space_{n}") // _str_space_{n}: + self.Emit("NOTQ", _AX) // NOTQ AX + self.Emit("ADDQ", _AX, _VAR_sp) // ADDQ AX, sp + self.Emit("LEAQ", jit.Sib(_RC, _RC, 1, 0), _AX) // LEAQ (RC)(RC), AX + self.slice_grow_ax("_str_loop_{n}") // GROW _str_loop_{n} + + /* empty string, check for double quote */ + if !doubleQuote { + self.Link("_str_empty_{n}") // _str_empty_{n}: + self.check_size(2) // SIZE $2 + self.add_text("\"\"") // TEXT $'""' + self.Link("_str_end_{n}") // _str_end_{n}: + } else { + self.Link("_str_empty_{n}") // _str_empty_{n}: + self.check_size(6) // SIZE $6 + self.add_text("\"\\\"\\\"\"") // TEXT $'"\"\""' + self.Link("_str_end_{n}") // _str_end_{n}: + } +} + +/** OpCode Assembler Functions **/ + +var ( + _T_json_Marshaler = rt.UnpackType(jsonMarshalerType) + _T_encoding_TextMarshaler = rt.UnpackType(encodingTextMarshalerType) +) + +var ( + _F_f64toa = jit.Imm(int64(native.S_f64toa)) + _F_f32toa = jit.Imm(int64(native.S_f32toa)) + _F_i64toa = jit.Imm(int64(native.S_i64toa)) + _F_u64toa = jit.Imm(int64(native.S_u64toa)) + _F_b64encode = jit.Imm(int64(_subr__b64encode)) +) + +var ( + _F_memmove = jit.Func(memmove) + _F_error_number = jit.Func(error_number) + _F_isValidNumber = jit.Func(isValidNumber) +) + +var ( + _F_iteratorStop = jit.Func(iteratorStop) + _F_iteratorNext = jit.Func(iteratorNext) + _F_iteratorStart = jit.Func(iteratorStart) +) + +var ( + _F_encodeTypedPointer obj.Addr + _F_encodeJsonMarshaler obj.Addr + _F_encodeTextMarshaler obj.Addr +) + +const ( + _MODE_AVX2 = 1 << 2 +) + +func init() { + _F_encodeTypedPointer = jit.Func(encodeTypedPointer) + _F_encodeJsonMarshaler = jit.Func(encodeJsonMarshaler) + _F_encodeTextMarshaler = jit.Func(encodeTextMarshaler) +} + +func (self *_Assembler) _asm_OP_null(_ *_Instr) { + self.check_size(4) + self.Emit("MOVL", jit.Imm(_IM_null), jit.Sib(_RP, _RL, 1, 0)) // MOVL $'null', (RP)(RL*1) + self.Emit("ADDQ", jit.Imm(4), _RL) // ADDQ $4, RL +} + +func (self *_Assembler) _asm_OP_empty_arr(_ *_Instr) { + self.Emit("BTQ", jit.Imm(int64(bitNoNullSliceOrMap)), _ARG_fv) + self.Sjmp("JC", "_empty_arr_{n}") + self._asm_OP_null(nil) + self.Sjmp("JMP", "_empty_arr_end_{n}") + self.Link("_empty_arr_{n}") + self.check_size(2) + self.Emit("MOVW", jit.Imm(_IM_array), jit.Sib(_RP, _RL, 1, 0)) + self.Emit("ADDQ", jit.Imm(2), _RL) + self.Link("_empty_arr_end_{n}") +} + +func (self *_Assembler) _asm_OP_empty_obj(_ *_Instr) { + self.Emit("BTQ", jit.Imm(int64(bitNoNullSliceOrMap)), _ARG_fv) + self.Sjmp("JC", "_empty_obj_{n}") + self._asm_OP_null(nil) + self.Sjmp("JMP", "_empty_obj_end_{n}") + self.Link("_empty_obj_{n}") + self.check_size(2) + self.Emit("MOVW", jit.Imm(_IM_object), jit.Sib(_RP, _RL, 1, 0)) + self.Emit("ADDQ", jit.Imm(2), _RL) + self.Link("_empty_obj_end_{n}") +} + +func (self *_Assembler) _asm_OP_bool(_ *_Instr) { + self.Emit("CMPB", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPB (SP.p), $0 + self.Sjmp("JE" , "_false_{n}") // JE _false_{n} + self.check_size(4) // SIZE $4 + self.Emit("MOVL", jit.Imm(_IM_true), jit.Sib(_RP, _RL, 1, 0)) // MOVL $'true', (RP)(RL*1) + self.Emit("ADDQ", jit.Imm(4), _RL) // ADDQ $4, RL + self.Sjmp("JMP" , "_end_{n}") // JMP _end_{n} + self.Link("_false_{n}") // _false_{n}: + self.check_size(5) // SIZE $5 + self.Emit("MOVL", jit.Imm(_IM_fals), jit.Sib(_RP, _RL, 1, 0)) // MOVL $'fals', (RP)(RL*1) + self.Emit("MOVB", jit.Imm('e'), jit.Sib(_RP, _RL, 1, 4)) // MOVB $'e', 4(RP)(RL*1) + self.Emit("ADDQ", jit.Imm(5), _RL) // ADDQ $5, RL + self.Link("_end_{n}") // _end_{n}: +} + +func (self *_Assembler) _asm_OP_i8(_ *_Instr) { + self.store_int(4, _F_i64toa, "MOVBQSX") +} + +func (self *_Assembler) _asm_OP_i16(_ *_Instr) { + self.store_int(6, _F_i64toa, "MOVWQSX") +} + +func (self *_Assembler) _asm_OP_i32(_ *_Instr) { + self.store_int(17, _F_i64toa, "MOVLQSX") +} + +func (self *_Assembler) _asm_OP_i64(_ *_Instr) { + self.store_int(21, _F_i64toa, "MOVQ") +} + +func (self *_Assembler) _asm_OP_u8(_ *_Instr) { + self.store_int(3, _F_u64toa, "MOVBQZX") +} + +func (self *_Assembler) _asm_OP_u16(_ *_Instr) { + self.store_int(5, _F_u64toa, "MOVWQZX") +} + +func (self *_Assembler) _asm_OP_u32(_ *_Instr) { + self.store_int(16, _F_u64toa, "MOVLQZX") +} + +func (self *_Assembler) _asm_OP_u64(_ *_Instr) { + self.store_int(20, _F_u64toa, "MOVQ") +} + +func (self *_Assembler) _asm_OP_f32(_ *_Instr) { + self.check_size(32) + self.Emit("MOVL" , jit.Ptr(_SP_p, 0), _AX) // MOVL (SP.p), AX + self.Emit("ANDL" , jit.Imm(_FM_exp32), _AX) // ANDL $_FM_exp32, AX + self.Emit("XORL" , jit.Imm(_FM_exp32), _AX) // XORL $_FM_exp32, AX + self.Sjmp("JZ" , _LB_error_nan_or_infinite) // JZ _error_nan_or_infinite + self.save_c() // SAVE $C_regs + self.rbuf_di() // MOVQ RP, DI + self.Emit("MOVSS" , jit.Ptr(_SP_p, 0), _X0) // MOVSS (SP.p), X0 + self.call_c(_F_f32toa) // CALL_C f64toa + self.Emit("ADDQ" , _AX, _RL) // ADDQ AX, RL +} + +func (self *_Assembler) _asm_OP_f64(_ *_Instr) { + self.check_size(32) + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("MOVQ" , jit.Imm(_FM_exp64), _CX) // MOVQ $_FM_exp64, CX + self.Emit("ANDQ" , _CX, _AX) // ANDQ CX, AX + self.Emit("XORQ" , _CX, _AX) // XORQ CX, AX + self.Sjmp("JZ" , _LB_error_nan_or_infinite) // JZ _error_nan_or_infinite + self.save_c() // SAVE $C_regs + self.rbuf_di() // MOVQ RP, DI + self.Emit("MOVSD" , jit.Ptr(_SP_p, 0), _X0) // MOVSD (SP.p), X0 + self.call_c(_F_f64toa) // CALL_C f64toa + self.Emit("ADDQ" , _AX, _RL) // ADDQ AX, RL +} + +func (self *_Assembler) _asm_OP_str(_ *_Instr) { + self.encode_string(false) +} + +func (self *_Assembler) _asm_OP_bin(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_SP_p, 8), _AX) // MOVQ 8(SP.p), AX + self.Emit("ADDQ", jit.Imm(2), _AX) // ADDQ $2, AX + self.Emit("MOVQ", jit.Imm(_IM_mulv), _CX) // MOVQ $_MF_mulv, CX + self.Emit("MOVQ", _DX, _R8) // MOVQ DX, R8 + self.From("MULQ", _CX) // MULQ CX + self.Emit("LEAQ", jit.Sib(_DX, _DX, 1, 1), _AX) // LEAQ 1(DX)(DX), AX + self.Emit("ORQ" , jit.Imm(2), _AX) // ORQ $2, AX + self.Emit("MOVQ", _R8, _DX) // MOVQ R8, DX + self.check_size_r(_AX, 0) // SIZE AX + self.add_char('"') // CHAR $'"' + self.save_c() // SAVE $REG_ffi + self.prep_buffer_c() // MOVE {buf}, DI + self.Emit("MOVQ", _SP_p, _SI) // MOVQ SP.p, SI + + /* check for AVX2 support */ + if !cpu.HasAVX2 { + self.Emit("XORL", _DX, _DX) // XORL DX, DX + } else { + self.Emit("MOVL", jit.Imm(_MODE_AVX2), _DX) // MOVL $_MODE_AVX2, DX + } + + /* call the encoder */ + self.call_c(_F_b64encode) // CALL b64encode + self.load_buffer() // LOAD {buf} + self.add_char('"') // CHAR $'"' +} + +func (self *_Assembler) _asm_OP_quote(_ *_Instr) { + self.encode_string(true) +} + +func (self *_Assembler) _asm_OP_number(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _CX) // MOVQ (SP.p), CX + self.Emit("TESTQ", _CX, _CX) // TESTQ CX, CX + self.Sjmp("JZ" , "_empty_{n}") // JZ _empty_{n} + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNZ" , "_number_next_{n}") + self.Emit("MOVQ", jit.Imm(int64(panicNilPointerOfNonEmptyString)), jit.Ptr(_SP, 0)) + self.Sjmp("JMP", _LB_panic) + self.Link("_number_next_{n}") + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ" , _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP) + self.call_go(_F_isValidNumber) // CALL_GO isValidNumber + self.Emit("CMPB" , jit.Ptr(_SP, 16), jit.Imm(0)) // CMPB 16(SP), $0 + self.Sjmp("JE" , _LB_error_invalid_number) // JE _error_invalid_number + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _AX) // MOVQ 8(SP.p), AX + self.check_size_r(_AX, 0) // SIZE AX + self.Emit("LEAQ" , jit.Sib(_RP, _RL, 1, 0), _AX) // LEAQ (RP)(RL), AX + self.Emit("ADDQ" , jit.Ptr(_SP_p, 8), _RL) // ADDQ 8(SP.p), RL + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVOU", jit.Ptr(_SP_p, 0), _X0) // MOVOU (SP.p), X0 + self.Emit("MOVOU", _X0, jit.Ptr(_SP, 8)) // MOVOU X0, 8(SP) + self.call_go(_F_memmove) // CALL_GO memmove + self.Sjmp("JMP" , "_done_{n}") // JMP _done_{n} + self.Link("_empty_{n}") // _empty_{n}: + self.check_size(1) // SIZE $1 + self.add_char('0') // CHAR $'0' + self.Link("_done_{n}") // _done_{n}: +} + +func (self *_Assembler) _asm_OP_eface(_ *_Instr) { + self.prep_buffer() // MOVE {buf}, (SP)s + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) + self.Emit("LEAQ" , jit.Ptr(_SP_p, 8), _AX) // LEAQ 8(SP.p), AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 16)) // MOVQ AX, 16(SP) + self.Emit("MOVQ" , _ST, jit.Ptr(_SP, 24)) // MOVQ ST, 24(SP) + self.Emit("MOVQ" , _ARG_fv, _AX) // MOVQ fv, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 32)) // MOVQ AX, 32(SP) + self.call_encoder(_F_encodeTypedPointer) // CALL encodeTypedPointer + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _ET) // MOVQ 40(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 48), _EP) // MOVQ 48(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error +} + +func (self *_Assembler) _asm_OP_iface(_ *_Instr) { + self.prep_buffer() // MOVE {buf}, (SP) + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("MOVQ" , jit.Ptr(_AX, 8), _AX) // MOVQ 8(AX), AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) + self.Emit("LEAQ" , jit.Ptr(_SP_p, 8), _AX) // LEAQ 8(SP.p), AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 16)) // MOVQ AX, 16(SP) + self.Emit("MOVQ" , _ST, jit.Ptr(_SP, 24)) // MOVQ ST, 24(SP) + self.Emit("MOVQ" , _ARG_fv, _AX) // MOVQ fv, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 32)) // MOVQ AX, 32(SP) + self.call_encoder(_F_encodeTypedPointer) // CALL encodeTypedPointer + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _ET) // MOVQ 40(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 48), _EP) // MOVQ 48(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error +} + +func (self *_Assembler) _asm_OP_byte(p *_Instr) { + self.check_size(1) + self.Emit("MOVB", jit.Imm(p.i64()), jit.Sib(_RP, _RL, 1, 0)) // MOVL p.vi(), (RP)(RL*1) + self.Emit("ADDQ", jit.Imm(1), _RL) // ADDQ $1, RL +} + +func (self *_Assembler) _asm_OP_text(p *_Instr) { + self.check_size(len(p.vs())) // SIZE ${len(p.vs())} + self.add_text(p.vs()) // TEXT ${p.vs()} +} + +func (self *_Assembler) _asm_OP_deref(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_SP_p, 0), _SP_p) // MOVQ (SP.p), SP.p +} + +func (self *_Assembler) _asm_OP_index(p *_Instr) { + self.Emit("MOVQ", jit.Imm(p.i64()), _AX) // MOVQ $p.vi(), AX + self.Emit("ADDQ", _AX, _SP_p) // ADDQ AX, SP.p +} + +func (self *_Assembler) _asm_OP_load(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, -24), _SP_x) // MOVQ -24(ST)(AX), SP.x + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, -8), _SP_p) // MOVQ -8(ST)(AX), SP.p + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, 0), _SP_q) // MOVQ (ST)(AX), SP.q +} + +func (self *_Assembler) _asm_OP_save(_ *_Instr) { + self.save_state() +} + +func (self *_Assembler) _asm_OP_drop(_ *_Instr) { + self.drop_state(_StateSize) +} + +func (self *_Assembler) _asm_OP_drop_2(_ *_Instr) { + self.drop_state(_StateSize * 2) // DROP $(_StateSize * 2) + self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 56)) // MOVOU X0, 56(ST)(AX) +} + +func (self *_Assembler) _asm_OP_recurse(p *_Instr) { + self.prep_buffer() // MOVE {buf}, (SP) + vt, pv := p.vp() + self.Emit("MOVQ", jit.Type(vt), _AX) // MOVQ $(type(p.vt())), AX + self.Emit("MOVQ", _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP) + + /* check for indirection */ + if !rt.UnpackType(vt).Indirect() { + self.Emit("MOVQ", _SP_p, _AX) // MOVQ SP.p, AX + } else { + self.Emit("MOVQ", _SP_p, _VAR_vp) // MOVQ SP.p, 48(SP) + self.Emit("LEAQ", _VAR_vp, _AX) // LEAQ 48(SP), AX + } + + /* call the encoder */ + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 16)) // MOVQ AX, 16(SP) + self.Emit("MOVQ" , _ST, jit.Ptr(_SP, 24)) // MOVQ ST, 24(SP) + self.Emit("MOVQ" , _ARG_fv, _AX) // MOVQ fv, AX + if pv { + self.Emit("BTCQ", jit.Imm(bitPointerValue), _AX) // BTCQ $1, AX + } + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 32)) // MOVQ AX, 32(SP) + self.call_encoder(_F_encodeTypedPointer) // CALL encodeTypedPointer + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _ET) // MOVQ 40(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 48), _EP) // MOVQ 48(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error +} + +func (self *_Assembler) _asm_OP_is_nil(p *_Instr) { + self.Emit("CMPQ", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPQ (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_nil_p1(p *_Instr) { + self.Emit("CMPQ", jit.Ptr(_SP_p, 8), jit.Imm(0)) // CMPQ 8(SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_1(p *_Instr) { + self.Emit("CMPB", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPB (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_2(p *_Instr) { + self.Emit("CMPW", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPW (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_4(p *_Instr) { + self.Emit("CMPL", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPL (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_8(p *_Instr) { + self.Emit("CMPQ", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPQ (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_map(p *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Xjmp("JZ" , p.vi()) // JZ p.vi() + self.Emit("CMPQ" , jit.Ptr(_AX, 0), jit.Imm(0)) // CMPQ (AX), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_goto(p *_Instr) { + self.Xjmp("JMP", p.vi()) +} + +func (self *_Assembler) _asm_OP_map_iter(p *_Instr) { + self.Emit("MOVQ" , jit.Type(p.vt()), _AX) // MOVQ $p.vt(), AX + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _CX) // MOVQ (SP.p), CX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP) + self.Emit("MOVQ" , _CX, jit.Ptr(_SP, 8)) // MOVQ CX, 8(SP) + self.Emit("MOVQ" , _ARG_fv, _AX) // MOVQ fv, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 16)) // MOVQ AX, 16(SP) + self.call_go(_F_iteratorStart) // CALL_GO iteratorStart + self.Emit("MOVQ" , jit.Ptr(_SP, 24), _SP_q) // MOVQ 24(SP), SP.q + self.Emit("MOVQ" , jit.Ptr(_SP, 32), _ET) // MOVQ 32(SP), ET + self.Emit("MOVQ" , jit.Ptr(_SP, 40), _EP) // MOVQ 40(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error +} + +func (self *_Assembler) _asm_OP_map_stop(_ *_Instr) { + self.Emit("MOVQ", _SP_q, jit.Ptr(_SP, 0)) // MOVQ SP.q, 0(SP) + self.call_go(_F_iteratorStop) // CALL_GO iteratorStop + self.Emit("XORL", _SP_q, _SP_q) // XORL SP.q, SP.q +} + +func (self *_Assembler) _asm_OP_map_check_key(p *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_SP_q, 0), _SP_p) // MOVQ (SP.q), SP.p + self.Emit("TESTQ", _SP_p, _SP_p) // TESTQ SP.p, SP.p + self.Xjmp("JZ" , p.vi()) // JNZ p.vi() +} + +func (self *_Assembler) _asm_OP_map_write_key(p *_Instr) { + self.Emit("BTQ", jit.Imm(bitSortMapKeys), _ARG_fv) // BTQ ${SortMapKeys}, fv + self.Sjmp("JNC", "_unordered_key_{n}") // JNC _unordered_key_{n} + self.encode_string(false) // STR $false + self.Xjmp("JMP", p.vi()) // JMP ${p.vi()} + self.Link("_unordered_key_{n}") // _unordered_key_{n}: +} + +func (self *_Assembler) _asm_OP_map_value_next(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_SP_q, 8), _SP_p) // MOVQ 8(SP.q), SP.p + self.Emit("MOVQ", _SP_q, jit.Ptr(_SP, 0)) // MOVQ SP.q, (SP) + self.call_go(_F_iteratorNext) // CALL_GO iteratorNext +} + +func (self *_Assembler) _asm_OP_slice_len(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _SP_x) // MOVQ 8(SP.p), SP.x + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _SP_p) // MOVQ (SP.p), SP.p + self.Emit("ORQ" , jit.Imm(1 << _S_init), _SP_f) // ORQ $(1<<_S_init), SP.f +} + +func (self *_Assembler) _asm_OP_slice_next(p *_Instr) { + self.Emit("TESTQ" , _SP_x, _SP_x) // TESTQ SP.x, SP.x + self.Xjmp("JZ" , p.vi()) // JZ p.vi() + self.Emit("SUBQ" , jit.Imm(1), _SP_x) // SUBQ $1, SP.x + self.Emit("BTRQ" , jit.Imm(_S_init), _SP_f) // BTRQ $_S_init, SP.f + self.Emit("LEAQ" , jit.Ptr(_SP_p, int64(p.vlen())), _AX) // LEAQ $(p.vlen())(SP.p), AX + self.Emit("CMOVQCC", _AX, _SP_p) // CMOVQNC AX, SP.p +} + +func (self *_Assembler) _asm_OP_marshal(p *_Instr) { + self.call_marshaler(_F_encodeJsonMarshaler, _T_json_Marshaler, p.vt()) +} + +func (self *_Assembler) _asm_OP_marshal_p(p *_Instr) { + if p.vk() != reflect.Ptr { + panic("marshal_p: invalid type") + } else { + self.call_marshaler_v(_F_encodeJsonMarshaler, _T_json_Marshaler, p.vt(), false) + } +} + +func (self *_Assembler) _asm_OP_marshal_text(p *_Instr) { + self.call_marshaler(_F_encodeTextMarshaler, _T_encoding_TextMarshaler, p.vt()) +} + +func (self *_Assembler) _asm_OP_marshal_text_p(p *_Instr) { + if p.vk() != reflect.Ptr { + panic("marshal_text_p: invalid type") + } else { + self.call_marshaler_v(_F_encodeTextMarshaler, _T_encoding_TextMarshaler, p.vt(), false) + } +} + +func (self *_Assembler) _asm_OP_cond_set(_ *_Instr) { + self.Emit("ORQ", jit.Imm(1 << _S_cond), _SP_f) // ORQ $(1<<_S_cond), SP.f +} + +func (self *_Assembler) _asm_OP_cond_testc(p *_Instr) { + self.Emit("BTRQ", jit.Imm(_S_cond), _SP_f) // BTRQ $_S_cond, SP.f + self.Xjmp("JC" , p.vi()) +} + +func (self *_Assembler) print_gc(i int, p1 *_Instr, p2 *_Instr) { + self.Emit("MOVQ", jit.Imm(int64(p2.op())), jit.Ptr(_SP, 16))// MOVQ $(p2.op()), 16(SP) + self.Emit("MOVQ", jit.Imm(int64(p1.op())), jit.Ptr(_SP, 8)) // MOVQ $(p1.op()), 8(SP) + self.Emit("MOVQ", jit.Imm(int64(i)), jit.Ptr(_SP, 0)) // MOVQ $(i), (SP) + self.call_go(_F_println) +} + +var ( + _V_writeBarrier = jit.Imm(int64(_runtime_writeBarrier)) + + _F_gcWriteBarrierAX = jit.Func(gcWriteBarrierAX) +) + +func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr) { + if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { + panic("rec contains AX!") + } + self.Emit("MOVQ", _V_writeBarrier, _R10) + self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", ptr, _AX) + self.xsave(_DI) + self.Emit("LEAQ", rec, _DI) + self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10) // MOVQ ${fn}, AX + self.Rjmp("CALL", _R10) + self.xload(_DI) + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", ptr, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/encoder/assembler_amd64_go117.go b/ihub/vendor/github.com/bytedance/sonic/encoder/assembler_amd64_go117.go new file mode 100644 index 0000000..8cd83e8 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/encoder/assembler_amd64_go117.go @@ -0,0 +1,1201 @@ +//go:build go1.17 && !go1.21 +// +build go1.17,!go1.21 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package encoder + +import ( + `fmt` + `reflect` + `strconv` + `unsafe` + + `github.com/bytedance/sonic/internal/cpu` + `github.com/bytedance/sonic/internal/jit` + `github.com/bytedance/sonic/internal/native/types` + `github.com/twitchyliquid64/golang-asm/obj` + `github.com/twitchyliquid64/golang-asm/obj/x86` + + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/rt` +) + +/** Register Allocations + * + * State Registers: + * + * %rbx : stack base + * %rdi : result pointer + * %rsi : result length + * %rdx : result capacity + * %r12 : sp->p + * %r13 : sp->q + * %r14 : sp->x + * %r15 : sp->f + * + * Error Registers: + * + * %r10 : error type register + * %r11 : error pointer register + */ + +/** Function Prototype & Stack Map + * + * func (buf *[]byte, p unsafe.Pointer, sb *_Stack, fv uint64) (err error) + * + * buf : (FP) + * p : 8(FP) + * sb : 16(FP) + * fv : 24(FP) + * err.vt : 32(FP) + * err.vp : 40(FP) + */ + +const ( + _S_cond = iota + _S_init +) + +const ( + _FP_args = 32 // 32 bytes for spill registers of arguments + _FP_fargs = 40 // 40 bytes for passing arguments to other Go functions + _FP_saves = 64 // 64 bytes for saving the registers before CALL instructions + _FP_locals = 24 // 24 bytes for local variables +) + +const ( + _FP_loffs = _FP_fargs + _FP_saves + _FP_offs = _FP_loffs + _FP_locals + // _FP_offs = _FP_loffs + _FP_locals + _FP_debug + _FP_size = _FP_offs + 8 // 8 bytes for the parent frame pointer + _FP_base = _FP_size + 8 // 8 bytes for the return address +) + +const ( + _FM_exp32 = 0x7f800000 + _FM_exp64 = 0x7ff0000000000000 +) + +const ( + _IM_null = 0x6c6c756e // 'null' + _IM_true = 0x65757274 // 'true' + _IM_fals = 0x736c6166 // 'fals' ('false' without the 'e') + _IM_open = 0x00225c22 // '"\"∅' + _IM_array = 0x5d5b // '[]' + _IM_object = 0x7d7b // '{}' + _IM_mulv = -0x5555555555555555 +) + +const ( + _LB_more_space = "_more_space" + _LB_more_space_return = "_more_space_return_" +) + +const ( + _LB_error = "_error" + _LB_error_too_deep = "_error_too_deep" + _LB_error_invalid_number = "_error_invalid_number" + _LB_error_nan_or_infinite = "_error_nan_or_infinite" + _LB_panic = "_panic" +) + +var ( + _AX = jit.Reg("AX") + _BX = jit.Reg("BX") + _CX = jit.Reg("CX") + _DX = jit.Reg("DX") + _DI = jit.Reg("DI") + _SI = jit.Reg("SI") + _BP = jit.Reg("BP") + _SP = jit.Reg("SP") + _R8 = jit.Reg("R8") + _R9 = jit.Reg("R9") +) + +var ( + _X0 = jit.Reg("X0") + _Y0 = jit.Reg("Y0") +) + +var ( + _ST = jit.Reg("R15") // can't use R14 since it's always scratched by Go... + _RP = jit.Reg("DI") + _RL = jit.Reg("SI") + _RC = jit.Reg("DX") +) + +var ( + _LR = jit.Reg("R9") + _ET = jit.Reg("AX") + _EP = jit.Reg("BX") +) + +var ( + _SP_p = jit.Reg("R10") // saved on BX when call_c + _SP_q = jit.Reg("R11") // saved on BP when call_c + _SP_x = jit.Reg("R12") + _SP_f = jit.Reg("R13") +) + +var ( + _ARG_rb = jit.Ptr(_SP, _FP_base) + _ARG_vp = jit.Ptr(_SP, _FP_base + 8) + _ARG_sb = jit.Ptr(_SP, _FP_base + 16) + _ARG_fv = jit.Ptr(_SP, _FP_base + 24) +) + +var ( + _RET_et = _ET + _RET_ep = _EP +) + +var ( + _VAR_sp = jit.Ptr(_SP, _FP_fargs + _FP_saves) + _VAR_dn = jit.Ptr(_SP, _FP_fargs + _FP_saves + 8) + _VAR_vp = jit.Ptr(_SP, _FP_fargs + _FP_saves + 16) +) + +var ( + _REG_ffi = []obj.Addr{ _RP, _RL, _RC} + _REG_b64 = []obj.Addr{_SP_p, _SP_q} + + _REG_all = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _RP, _RL, _RC} + _REG_ms = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _LR} + _REG_enc = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _RL} +) + +type _Assembler struct { + jit.BaseAssembler + p _Program + x int + name string +} + +func newAssembler(p _Program) *_Assembler { + return new(_Assembler).Init(p) +} + +/** Assembler Interface **/ + +func (self *_Assembler) Load() _Encoder { + return ptoenc(self.BaseAssembler.Load("encode_"+self.name, _FP_size, _FP_args, argPtrs, localPtrs)) +} + +func (self *_Assembler) Init(p _Program) *_Assembler { + self.p = p + self.BaseAssembler.Init(self.compile) + return self +} + +func (self *_Assembler) compile() { + self.prologue() + self.instrs() + self.epilogue() + self.builtins() +} + +/** Assembler Stages **/ + +var _OpFuncTab = [256]func(*_Assembler, *_Instr) { + _OP_null : (*_Assembler)._asm_OP_null, + _OP_empty_arr : (*_Assembler)._asm_OP_empty_arr, + _OP_empty_obj : (*_Assembler)._asm_OP_empty_obj, + _OP_bool : (*_Assembler)._asm_OP_bool, + _OP_i8 : (*_Assembler)._asm_OP_i8, + _OP_i16 : (*_Assembler)._asm_OP_i16, + _OP_i32 : (*_Assembler)._asm_OP_i32, + _OP_i64 : (*_Assembler)._asm_OP_i64, + _OP_u8 : (*_Assembler)._asm_OP_u8, + _OP_u16 : (*_Assembler)._asm_OP_u16, + _OP_u32 : (*_Assembler)._asm_OP_u32, + _OP_u64 : (*_Assembler)._asm_OP_u64, + _OP_f32 : (*_Assembler)._asm_OP_f32, + _OP_f64 : (*_Assembler)._asm_OP_f64, + _OP_str : (*_Assembler)._asm_OP_str, + _OP_bin : (*_Assembler)._asm_OP_bin, + _OP_quote : (*_Assembler)._asm_OP_quote, + _OP_number : (*_Assembler)._asm_OP_number, + _OP_eface : (*_Assembler)._asm_OP_eface, + _OP_iface : (*_Assembler)._asm_OP_iface, + _OP_byte : (*_Assembler)._asm_OP_byte, + _OP_text : (*_Assembler)._asm_OP_text, + _OP_deref : (*_Assembler)._asm_OP_deref, + _OP_index : (*_Assembler)._asm_OP_index, + _OP_load : (*_Assembler)._asm_OP_load, + _OP_save : (*_Assembler)._asm_OP_save, + _OP_drop : (*_Assembler)._asm_OP_drop, + _OP_drop_2 : (*_Assembler)._asm_OP_drop_2, + _OP_recurse : (*_Assembler)._asm_OP_recurse, + _OP_is_nil : (*_Assembler)._asm_OP_is_nil, + _OP_is_nil_p1 : (*_Assembler)._asm_OP_is_nil_p1, + _OP_is_zero_1 : (*_Assembler)._asm_OP_is_zero_1, + _OP_is_zero_2 : (*_Assembler)._asm_OP_is_zero_2, + _OP_is_zero_4 : (*_Assembler)._asm_OP_is_zero_4, + _OP_is_zero_8 : (*_Assembler)._asm_OP_is_zero_8, + _OP_is_zero_map : (*_Assembler)._asm_OP_is_zero_map, + _OP_goto : (*_Assembler)._asm_OP_goto, + _OP_map_iter : (*_Assembler)._asm_OP_map_iter, + _OP_map_stop : (*_Assembler)._asm_OP_map_stop, + _OP_map_check_key : (*_Assembler)._asm_OP_map_check_key, + _OP_map_write_key : (*_Assembler)._asm_OP_map_write_key, + _OP_map_value_next : (*_Assembler)._asm_OP_map_value_next, + _OP_slice_len : (*_Assembler)._asm_OP_slice_len, + _OP_slice_next : (*_Assembler)._asm_OP_slice_next, + _OP_marshal : (*_Assembler)._asm_OP_marshal, + _OP_marshal_p : (*_Assembler)._asm_OP_marshal_p, + _OP_marshal_text : (*_Assembler)._asm_OP_marshal_text, + _OP_marshal_text_p : (*_Assembler)._asm_OP_marshal_text_p, + _OP_cond_set : (*_Assembler)._asm_OP_cond_set, + _OP_cond_testc : (*_Assembler)._asm_OP_cond_testc, +} + +func (self *_Assembler) instr(v *_Instr) { + if fn := _OpFuncTab[v.op()]; fn != nil { + fn(self, v) + } else { + panic(fmt.Sprintf("invalid opcode: %d", v.op())) + } +} + +func (self *_Assembler) instrs() { + for i, v := range self.p { + self.Mark(i) + self.instr(&v) + self.debug_instr(i, &v) + } +} + +func (self *_Assembler) builtins() { + self.more_space() + self.error_too_deep() + self.error_invalid_number() + self.error_nan_or_infinite() + self.go_panic() +} + +func (self *_Assembler) epilogue() { + self.Mark(len(self.p)) + self.Emit("XORL", _ET, _ET) + self.Emit("XORL", _EP, _EP) + self.Link(_LB_error) + self.Emit("MOVQ", _ARG_rb, _CX) // MOVQ rb<>+0(FP), CX + self.Emit("MOVQ", _RL, jit.Ptr(_CX, 8)) // MOVQ RL, 8(CX) + self.Emit("MOVQ", jit.Imm(0), _ARG_rb) // MOVQ AX, rb<>+0(FP) + self.Emit("MOVQ", jit.Imm(0), _ARG_vp) // MOVQ BX, vp<>+8(FP) + self.Emit("MOVQ", jit.Imm(0), _ARG_sb) // MOVQ CX, sb<>+16(FP) + self.Emit("MOVQ", jit.Ptr(_SP, _FP_offs), _BP) // MOVQ _FP_offs(SP), BP + self.Emit("ADDQ", jit.Imm(_FP_size), _SP) // ADDQ $_FP_size, SP + self.Emit("RET") // RET +} + +func (self *_Assembler) prologue() { + self.Emit("SUBQ", jit.Imm(_FP_size), _SP) // SUBQ $_FP_size, SP + self.Emit("MOVQ", _BP, jit.Ptr(_SP, _FP_offs)) // MOVQ BP, _FP_offs(SP) + self.Emit("LEAQ", jit.Ptr(_SP, _FP_offs), _BP) // LEAQ _FP_offs(SP), BP + self.Emit("MOVQ", _AX, _ARG_rb) // MOVQ AX, rb<>+0(FP) + self.Emit("MOVQ", _BX, _ARG_vp) // MOVQ BX, vp<>+8(FP) + self.Emit("MOVQ", _CX, _ARG_sb) // MOVQ CX, sb<>+16(FP) + self.Emit("MOVQ", _DI, _ARG_fv) // MOVQ DI, rb<>+24(FP) + self.Emit("MOVQ", jit.Ptr(_AX, 0), _RP) // MOVQ (AX) , DI + self.Emit("MOVQ", jit.Ptr(_AX, 8), _RL) // MOVQ 8(AX) , SI + self.Emit("MOVQ", jit.Ptr(_AX, 16), _RC) // MOVQ 16(AX), DX + self.Emit("MOVQ", _BX, _SP_p) // MOVQ BX, R10 + self.Emit("MOVQ", _CX, _ST) // MOVQ CX, R8 + self.Emit("XORL", _SP_x, _SP_x) // XORL R10, R12 + self.Emit("XORL", _SP_f, _SP_f) // XORL R11, R13 + self.Emit("XORL", _SP_q, _SP_q) // XORL R13, R11 +} + +/** Assembler Inline Functions **/ + +func (self *_Assembler) xsave(reg ...obj.Addr) { + for i, v := range reg { + if i > _FP_saves / 8 - 1 { + panic("too many registers to save") + } else { + self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs + int64(i) * 8)) + } + } +} + +func (self *_Assembler) xload(reg ...obj.Addr) { + for i, v := range reg { + if i > _FP_saves / 8 - 1 { + panic("too many registers to load") + } else { + self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs + int64(i) * 8), v) + } + } +} + +func (self *_Assembler) rbuf_di() { + if _RP.Reg != x86.REG_DI { + panic("register allocation messed up: RP != DI") + } else { + self.Emit("ADDQ", _RL, _RP) + } +} + +func (self *_Assembler) store_int(nd int, fn obj.Addr, ins string) { + self.check_size(nd) + self.save_c() // SAVE $C_regs + self.rbuf_di() // MOVQ RP, DI + self.Emit(ins, jit.Ptr(_SP_p, 0), _SI) // $ins (SP.p), SI + self.call_c(fn) // CALL_C $fn + self.Emit("ADDQ", _AX, _RL) // ADDQ AX, RL +} + +func (self *_Assembler) store_str(s string) { + i := 0 + m := rt.Str2Mem(s) + + /* 8-byte stores */ + for i <= len(m) - 8 { + self.Emit("MOVQ", jit.Imm(rt.Get64(m[i:])), _AX) // MOVQ $s[i:], AX + self.Emit("MOVQ", _AX, jit.Sib(_RP, _RL, 1, int64(i))) // MOVQ AX, i(RP)(RL) + i += 8 + } + + /* 4-byte stores */ + if i <= len(m) - 4 { + self.Emit("MOVL", jit.Imm(int64(rt.Get32(m[i:]))), jit.Sib(_RP, _RL, 1, int64(i))) // MOVL $s[i:], i(RP)(RL) + i += 4 + } + + /* 2-byte stores */ + if i <= len(m) - 2 { + self.Emit("MOVW", jit.Imm(int64(rt.Get16(m[i:]))), jit.Sib(_RP, _RL, 1, int64(i))) // MOVW $s[i:], i(RP)(RL) + i += 2 + } + + /* last byte */ + if i < len(m) { + self.Emit("MOVB", jit.Imm(int64(m[i])), jit.Sib(_RP, _RL, 1, int64(i))) // MOVB $s[i:], i(RP)(RL) + } +} + +func (self *_Assembler) check_size(n int) { + self.check_size_rl(jit.Ptr(_RL, int64(n))) +} + +func (self *_Assembler) check_size_r(r obj.Addr, d int) { + self.check_size_rl(jit.Sib(_RL, r, 1, int64(d))) +} + +func (self *_Assembler) check_size_rl(v obj.Addr) { + idx := self.x + key := _LB_more_space_return + strconv.Itoa(idx) + + /* the following code relies on LR == R9 to work */ + if _LR.Reg != x86.REG_R9 { + panic("register allocation messed up: LR != R9") + } + + /* check for buffer capacity */ + self.x++ + self.Emit("LEAQ", v, _AX) // LEAQ $v, AX + self.Emit("CMPQ", _AX, _RC) // CMPQ AX, RC + self.Sjmp("JBE" , key) // JBE _more_space_return_{n} + self.slice_grow_ax(key) // GROW $key + self.Link(key) // _more_space_return_{n}: +} + +func (self *_Assembler) slice_grow_ax(ret string) { + self.Byte(0x4c, 0x8d, 0x0d) // LEAQ ?(PC), R9 + self.Sref(ret, 4) // .... &ret + self.Sjmp("JMP" , _LB_more_space) // JMP _more_space +} + +/** State Stack Helpers **/ + +const ( + _StateSize = int64(unsafe.Sizeof(_State{})) + _StackLimit = _MaxStack * _StateSize +) + +func (self *_Assembler) save_state() { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _CX) // MOVQ (ST), CX + self.Emit("LEAQ", jit.Ptr(_CX, _StateSize), _R9) // LEAQ _StateSize(CX), R9 + self.Emit("CMPQ", _R9, jit.Imm(_StackLimit)) // CMPQ R9, $_StackLimit + self.Sjmp("JAE" , _LB_error_too_deep) // JA _error_too_deep + self.Emit("MOVQ", _SP_x, jit.Sib(_ST, _CX, 1, 8)) // MOVQ SP.x, 8(ST)(CX) + self.Emit("MOVQ", _SP_f, jit.Sib(_ST, _CX, 1, 16)) // MOVQ SP.f, 16(ST)(CX) + self.WriteRecNotAX(0, _SP_p, jit.Sib(_ST, _CX, 1, 24)) // MOVQ SP.p, 24(ST)(CX) + self.WriteRecNotAX(1, _SP_q, jit.Sib(_ST, _CX, 1, 32)) // MOVQ SP.q, 32(ST)(CX) + self.Emit("MOVQ", _R9, jit.Ptr(_ST, 0)) // MOVQ R9, (ST) +} + +func (self *_Assembler) drop_state(decr int64) { + self.Emit("MOVQ" , jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("SUBQ" , jit.Imm(decr), _AX) // SUBQ $decr, AX + self.Emit("MOVQ" , _AX, jit.Ptr(_ST, 0)) // MOVQ AX, (ST) + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 8), _SP_x) // MOVQ 8(ST)(AX), SP.x + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 16), _SP_f) // MOVQ 16(ST)(AX), SP.f + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 24), _SP_p) // MOVQ 24(ST)(AX), SP.p + self.Emit("MOVQ" , jit.Sib(_ST, _AX, 1, 32), _SP_q) // MOVQ 32(ST)(AX), SP.q + self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0 + self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 8)) // MOVOU X0, 8(ST)(AX) + self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 24)) // MOVOU X0, 24(ST)(AX) +} + +/** Buffer Helpers **/ + +func (self *_Assembler) add_char(ch byte) { + self.Emit("MOVB", jit.Imm(int64(ch)), jit.Sib(_RP, _RL, 1, 0)) // MOVB $ch, (RP)(RL) + self.Emit("ADDQ", jit.Imm(1), _RL) // ADDQ $1, RL +} + +func (self *_Assembler) add_long(ch uint32, n int64) { + self.Emit("MOVL", jit.Imm(int64(ch)), jit.Sib(_RP, _RL, 1, 0)) // MOVL $ch, (RP)(RL) + self.Emit("ADDQ", jit.Imm(n), _RL) // ADDQ $n, RL +} + +func (self *_Assembler) add_text(ss string) { + self.store_str(ss) // TEXT $ss + self.Emit("ADDQ", jit.Imm(int64(len(ss))), _RL) // ADDQ ${len(ss)}, RL +} + +// get *buf at AX +func (self *_Assembler) prep_buffer_AX() { + self.Emit("MOVQ", _ARG_rb, _AX) // MOVQ rb<>+0(FP), AX + self.Emit("MOVQ", _RL, jit.Ptr(_AX, 8)) // MOVQ RL, 8(AX) +} + +func (self *_Assembler) save_buffer() { + self.Emit("MOVQ", _ARG_rb, _CX) // MOVQ rb<>+0(FP), CX + self.Emit("MOVQ", _RP, jit.Ptr(_CX, 0)) // MOVQ RP, (CX) + self.Emit("MOVQ", _RL, jit.Ptr(_CX, 8)) // MOVQ RL, 8(CX) + self.Emit("MOVQ", _RC, jit.Ptr(_CX, 16)) // MOVQ RC, 16(CX) +} + +// get *buf at AX +func (self *_Assembler) load_buffer_AX() { + self.Emit("MOVQ", _ARG_rb, _AX) // MOVQ rb<>+0(FP), AX + self.Emit("MOVQ", jit.Ptr(_AX, 0), _RP) // MOVQ (AX), RP + self.Emit("MOVQ", jit.Ptr(_AX, 8), _RL) // MOVQ 8(AX), RL + self.Emit("MOVQ", jit.Ptr(_AX, 16), _RC) // MOVQ 16(AX), RC +} + +/** Function Interface Helpers **/ + +func (self *_Assembler) call(pc obj.Addr) { + self.Emit("MOVQ", pc, _LR) // MOVQ $pc, AX + self.Rjmp("CALL", _LR) // CALL AX +} + +func (self *_Assembler) save_c() { + self.xsave(_REG_ffi...) // SAVE $REG_ffi +} + +func (self *_Assembler) call_b64(pc obj.Addr) { + self.xsave(_REG_b64...) // SAVE $REG_all + self.call(pc) // CALL $pc + self.xload(_REG_b64...) // LOAD $REG_ffi +} + +func (self *_Assembler) call_c(pc obj.Addr) { + self.Emit("XCHGQ", _SP_p, _BX) + self.Emit("XCHGQ", _SP_q, _BP) + self.call(pc) // CALL $pc + self.xload(_REG_ffi...) // LOAD $REG_ffi + self.Emit("XCHGQ", _SP_p, _BX) + self.Emit("XCHGQ", _SP_q, _BP) +} + +func (self *_Assembler) call_go(pc obj.Addr) { + self.xsave(_REG_all...) // SAVE $REG_all + self.call(pc) // CALL $pc + self.xload(_REG_all...) // LOAD $REG_all +} + +func (self *_Assembler) call_more_space(pc obj.Addr) { + self.xsave(_REG_ms...) // SAVE $REG_all + self.call(pc) // CALL $pc + self.xload(_REG_ms...) // LOAD $REG_all +} + +func (self *_Assembler) call_encoder(pc obj.Addr) { + self.xsave(_REG_enc...) // SAVE $REG_all + self.call(pc) // CALL $pc + self.xload(_REG_enc...) // LOAD $REG_all +} + +func (self *_Assembler) call_marshaler(fn obj.Addr, it *rt.GoType, vt reflect.Type) { + switch vt.Kind() { + case reflect.Interface : self.call_marshaler_i(fn, it) + case reflect.Ptr, reflect.Map : self.call_marshaler_v(fn, it, vt, true) + default : self.call_marshaler_v(fn, it, vt, false) + } +} + +func (self *_Assembler) call_marshaler_i(fn obj.Addr, it *rt.GoType) { + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JZ" , "_null_{n}") // JZ _null_{n} + self.Emit("MOVQ" , _AX, _BX) // MOVQ AX, BX + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _CX) // MOVQ 8(SP.p), CX + self.Emit("MOVQ" , jit.Gtype(it), _AX) // MOVQ $it, AX + self.call_go(_F_assertI2I) // CALL_GO assertI2I + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JZ" , "_null_{n}") // JZ _null_{n} + self.Emit("MOVQ", _BX, _CX) // MOVQ BX, CX + self.Emit("MOVQ", _AX, _BX) // MOVQ AX, BX + self.prep_buffer_AX() + self.Emit("MOVQ", _ARG_fv, _DI) // MOVQ ARG.fv, DI + self.call_go(fn) // CALL $fn + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error + self.load_buffer_AX() + self.Sjmp("JMP" , "_done_{n}") // JMP _done_{n} + self.Link("_null_{n}") // _null_{n}: + self.check_size(4) // SIZE $4 + self.Emit("MOVL", jit.Imm(_IM_null), jit.Sib(_RP, _RL, 1, 0)) // MOVL $'null', (RP)(RL*1) + self.Emit("ADDQ", jit.Imm(4), _RL) // ADDQ $4, RL + self.Link("_done_{n}") // _done_{n}: +} + +func (self *_Assembler) call_marshaler_v(fn obj.Addr, it *rt.GoType, vt reflect.Type, deref bool) { + self.prep_buffer_AX() // MOVE {buf}, (SP) + self.Emit("MOVQ", jit.Itab(it, vt), _BX) // MOVQ $(itab(it, vt)), BX + + /* dereference the pointer if needed */ + if !deref { + self.Emit("MOVQ", _SP_p, _CX) // MOVQ SP.p, CX + } else { + self.Emit("MOVQ", jit.Ptr(_SP_p, 0), _CX) // MOVQ 0(SP.p), CX + } + + /* call the encoder, and perform error checks */ + self.Emit("MOVQ", _ARG_fv, _DI) // MOVQ ARG.fv, DI + self.call_go(fn) // CALL $fn + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error + self.load_buffer_AX() +} + +/** Builtin: _more_space **/ + +var ( + _T_byte = jit.Type(byteType) + _F_growslice = jit.Func(growslice) +) + +// AX must saving n +func (self *_Assembler) more_space() { + self.Link(_LB_more_space) + self.Emit("MOVQ", _RP, _BX) // MOVQ DI, BX + self.Emit("MOVQ", _RL, _CX) // MOVQ SI, CX + self.Emit("MOVQ", _RC, _DI) // MOVQ DX, DI + self.Emit("MOVQ", _AX, _SI) // MOVQ AX, SI + self.Emit("MOVQ", _T_byte, _AX) // MOVQ $_T_byte, AX + self.call_more_space(_F_growslice) // CALL $pc + self.Emit("MOVQ", _AX, _RP) // MOVQ AX, DI + self.Emit("MOVQ", _BX, _RL) // MOVQ BX, SI + self.Emit("MOVQ", _CX, _RC) // MOVQ CX, DX + self.save_buffer() // SAVE {buf} + self.Rjmp("JMP" , _LR) // JMP LR +} + +/** Builtin Errors **/ + +var ( + _V_ERR_too_deep = jit.Imm(int64(uintptr(unsafe.Pointer(_ERR_too_deep)))) + _V_ERR_nan_or_infinite = jit.Imm(int64(uintptr(unsafe.Pointer(_ERR_nan_or_infinite)))) + _I_json_UnsupportedValueError = jit.Itab(rt.UnpackType(errorType), jsonUnsupportedValueType) +) + +func (self *_Assembler) error_too_deep() { + self.Link(_LB_error_too_deep) + self.Emit("MOVQ", _V_ERR_too_deep, _EP) // MOVQ $_V_ERR_too_deep, EP + self.Emit("MOVQ", _I_json_UnsupportedValueError, _ET) // MOVQ $_I_json_UnsupportedValuError, ET + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) error_invalid_number() { + self.Link(_LB_error_invalid_number) + self.Emit("MOVQ", jit.Ptr(_SP_p, 0), _AX) // MOVQ 0(SP), AX + self.Emit("MOVQ", jit.Ptr(_SP_p, 8), _BX) // MOVQ 8(SP), BX + self.call_go(_F_error_number) // CALL_GO error_number + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +func (self *_Assembler) error_nan_or_infinite() { + self.Link(_LB_error_nan_or_infinite) + self.Emit("MOVQ", _V_ERR_nan_or_infinite, _EP) // MOVQ $_V_ERR_nan_or_infinite, EP + self.Emit("MOVQ", _I_json_UnsupportedValueError, _ET) // MOVQ $_I_json_UnsupportedValuError, ET + self.Sjmp("JMP" , _LB_error) // JMP _error +} + +/** String Encoding Routine **/ + +var ( + _F_quote = jit.Imm(int64(native.S_quote)) + _F_panic = jit.Func(goPanic) +) + +func (self *_Assembler) go_panic() { + self.Link(_LB_panic) + self.Emit("MOVQ", _SP_p, _BX) + self.call_go(_F_panic) +} + +func (self *_Assembler) encode_string(doubleQuote bool) { + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _AX) // MOVQ 8(SP.p), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JZ" , "_str_empty_{n}") // JZ _str_empty_{n} + self.Emit("CMPQ", jit.Ptr(_SP_p, 0), jit.Imm(0)) + self.Sjmp("JNE" , "_str_next_{n}") + self.Emit("MOVQ", jit.Imm(int64(panicNilPointerOfNonEmptyString)), _AX) + self.Sjmp("JMP", _LB_panic) + self.Link("_str_next_{n}") + + /* openning quote, check for double quote */ + if !doubleQuote { + self.check_size_r(_AX, 2) // SIZE $2 + self.add_char('"') // CHAR $'"' + } else { + self.check_size_r(_AX, 6) // SIZE $6 + self.add_long(_IM_open, 3) // TEXT $`"\"` + } + + /* quoting loop */ + self.Emit("XORL", _AX, _AX) // XORL AX, AX + self.Emit("MOVQ", _AX, _VAR_sp) // MOVQ AX, sp + self.Link("_str_loop_{n}") // _str_loop_{n}: + self.save_c() // SAVE $REG_ffi + + /* load the output buffer first, and then input buffer, + * because the parameter registers collide with RP / RL / RC */ + self.Emit("MOVQ", _RC, _CX) // MOVQ RC, CX + self.Emit("SUBQ", _RL, _CX) // SUBQ RL, CX + self.Emit("MOVQ", _CX, _VAR_dn) // MOVQ CX, dn + self.Emit("LEAQ", jit.Sib(_RP, _RL, 1, 0), _DX) // LEAQ (RP)(RL), DX + self.Emit("LEAQ", _VAR_dn, _CX) // LEAQ dn, CX + self.Emit("MOVQ", _VAR_sp, _AX) // MOVQ sp, AX + self.Emit("MOVQ", jit.Ptr(_SP_p, 0), _DI) // MOVQ (SP.p), DI + self.Emit("MOVQ", jit.Ptr(_SP_p, 8), _SI) // MOVQ 8(SP.p), SI + self.Emit("ADDQ", _AX, _DI) // ADDQ AX, DI + self.Emit("SUBQ", _AX, _SI) // SUBQ AX, SI + + /* set the flags based on `doubleQuote` */ + if !doubleQuote { + self.Emit("XORL", _R8, _R8) // XORL R8, R8 + } else { + self.Emit("MOVL", jit.Imm(types.F_DOUBLE_UNQUOTE), _R8) // MOVL ${types.F_DOUBLE_UNQUOTE}, R8 + } + + /* call the native quoter */ + self.call_c(_F_quote) // CALL quote + self.Emit("ADDQ" , _VAR_dn, _RL) // ADDQ dn, RL + + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , "_str_space_{n}") // JS _str_space_{n} + + /* close the string, check for double quote */ + if !doubleQuote { + self.check_size(1) // SIZE $1 + self.add_char('"') // CHAR $'"' + self.Sjmp("JMP", "_str_end_{n}") // JMP _str_end_{n} + } else { + self.check_size(3) // SIZE $3 + self.add_text("\\\"\"") // TEXT $'\""' + self.Sjmp("JMP", "_str_end_{n}") // JMP _str_end_{n} + } + + /* not enough space to contain the quoted string */ + self.Link("_str_space_{n}") // _str_space_{n}: + self.Emit("NOTQ", _AX) // NOTQ AX + self.Emit("ADDQ", _AX, _VAR_sp) // ADDQ AX, sp + self.Emit("LEAQ", jit.Sib(_RC, _RC, 1, 0), _AX) // LEAQ (RC)(RC), AX + self.slice_grow_ax("_str_loop_{n}") // GROW _str_loop_{n} + + /* empty string, check for double quote */ + if !doubleQuote { + self.Link("_str_empty_{n}") // _str_empty_{n}: + self.check_size(2) // SIZE $2 + self.add_text("\"\"") // TEXT $'""' + self.Link("_str_end_{n}") // _str_end_{n}: + } else { + self.Link("_str_empty_{n}") // _str_empty_{n}: + self.check_size(6) // SIZE $6 + self.add_text("\"\\\"\\\"\"") // TEXT $'"\"\""' + self.Link("_str_end_{n}") // _str_end_{n}: + } +} + +/** OpCode Assembler Functions **/ + +var ( + _T_json_Marshaler = rt.UnpackType(jsonMarshalerType) + _T_encoding_TextMarshaler = rt.UnpackType(encodingTextMarshalerType) +) + +var ( + _F_f64toa = jit.Imm(int64(native.S_f64toa)) + _F_f32toa = jit.Imm(int64(native.S_f32toa)) + _F_i64toa = jit.Imm(int64(native.S_i64toa)) + _F_u64toa = jit.Imm(int64(native.S_u64toa)) + _F_b64encode = jit.Imm(int64(_subr__b64encode)) +) + +var ( + _F_memmove = jit.Func(memmove) + _F_error_number = jit.Func(error_number) + _F_isValidNumber = jit.Func(isValidNumber) +) + +var ( + _F_iteratorStop = jit.Func(iteratorStop) + _F_iteratorNext = jit.Func(iteratorNext) + _F_iteratorStart = jit.Func(iteratorStart) +) + +var ( + _F_encodeTypedPointer obj.Addr + _F_encodeJsonMarshaler obj.Addr + _F_encodeTextMarshaler obj.Addr +) + +const ( + _MODE_AVX2 = 1 << 2 +) + +func init() { + _F_encodeTypedPointer = jit.Func(encodeTypedPointer) + _F_encodeJsonMarshaler = jit.Func(encodeJsonMarshaler) + _F_encodeTextMarshaler = jit.Func(encodeTextMarshaler) +} + +func (self *_Assembler) _asm_OP_null(_ *_Instr) { + self.check_size(4) + self.Emit("MOVL", jit.Imm(_IM_null), jit.Sib(_RP, _RL, 1, 0)) // MOVL $'null', (RP)(RL*1) + self.Emit("ADDQ", jit.Imm(4), _RL) // ADDQ $4, RL +} + +func (self *_Assembler) _asm_OP_empty_arr(_ *_Instr) { + self.Emit("BTQ", jit.Imm(int64(bitNoNullSliceOrMap)), _ARG_fv) + self.Sjmp("JC", "_empty_arr_{n}") + self._asm_OP_null(nil) + self.Sjmp("JMP", "_empty_arr_end_{n}") + self.Link("_empty_arr_{n}") + self.check_size(2) + self.Emit("MOVW", jit.Imm(_IM_array), jit.Sib(_RP, _RL, 1, 0)) + self.Emit("ADDQ", jit.Imm(2), _RL) + self.Link("_empty_arr_end_{n}") +} + +func (self *_Assembler) _asm_OP_empty_obj(_ *_Instr) { + self.Emit("BTQ", jit.Imm(int64(bitNoNullSliceOrMap)), _ARG_fv) + self.Sjmp("JC", "_empty_obj_{n}") + self._asm_OP_null(nil) + self.Sjmp("JMP", "_empty_obj_end_{n}") + self.Link("_empty_obj_{n}") + self.check_size(2) + self.Emit("MOVW", jit.Imm(_IM_object), jit.Sib(_RP, _RL, 1, 0)) + self.Emit("ADDQ", jit.Imm(2), _RL) + self.Link("_empty_obj_end_{n}") +} + +func (self *_Assembler) _asm_OP_bool(_ *_Instr) { + self.Emit("CMPB", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPB (SP.p), $0 + self.Sjmp("JE" , "_false_{n}") // JE _false_{n} + self.check_size(4) // SIZE $4 + self.Emit("MOVL", jit.Imm(_IM_true), jit.Sib(_RP, _RL, 1, 0)) // MOVL $'true', (RP)(RL*1) + self.Emit("ADDQ", jit.Imm(4), _RL) // ADDQ $4, RL + self.Sjmp("JMP" , "_end_{n}") // JMP _end_{n} + self.Link("_false_{n}") // _false_{n}: + self.check_size(5) // SIZE $5 + self.Emit("MOVL", jit.Imm(_IM_fals), jit.Sib(_RP, _RL, 1, 0)) // MOVL $'fals', (RP)(RL*1) + self.Emit("MOVB", jit.Imm('e'), jit.Sib(_RP, _RL, 1, 4)) // MOVB $'e', 4(RP)(RL*1) + self.Emit("ADDQ", jit.Imm(5), _RL) // ADDQ $5, RL + self.Link("_end_{n}") // _end_{n}: +} + +func (self *_Assembler) _asm_OP_i8(_ *_Instr) { + self.store_int(4, _F_i64toa, "MOVBQSX") +} + +func (self *_Assembler) _asm_OP_i16(_ *_Instr) { + self.store_int(6, _F_i64toa, "MOVWQSX") +} + +func (self *_Assembler) _asm_OP_i32(_ *_Instr) { + self.store_int(17, _F_i64toa, "MOVLQSX") +} + +func (self *_Assembler) _asm_OP_i64(_ *_Instr) { + self.store_int(21, _F_i64toa, "MOVQ") +} + +func (self *_Assembler) _asm_OP_u8(_ *_Instr) { + self.store_int(3, _F_u64toa, "MOVBQZX") +} + +func (self *_Assembler) _asm_OP_u16(_ *_Instr) { + self.store_int(5, _F_u64toa, "MOVWQZX") +} + +func (self *_Assembler) _asm_OP_u32(_ *_Instr) { + self.store_int(16, _F_u64toa, "MOVLQZX") +} + +func (self *_Assembler) _asm_OP_u64(_ *_Instr) { + self.store_int(20, _F_u64toa, "MOVQ") +} + +func (self *_Assembler) _asm_OP_f32(_ *_Instr) { + self.check_size(32) + self.Emit("MOVL" , jit.Ptr(_SP_p, 0), _AX) // MOVL (SP.p), AX + self.Emit("ANDL" , jit.Imm(_FM_exp32), _AX) // ANDL $_FM_exp32, AX + self.Emit("XORL" , jit.Imm(_FM_exp32), _AX) // XORL $_FM_exp32, AX + self.Sjmp("JZ" , _LB_error_nan_or_infinite) // JZ _error_nan_or_infinite + self.save_c() // SAVE $C_regs + self.rbuf_di() // MOVQ RP, DI + self.Emit("MOVSS" , jit.Ptr(_SP_p, 0), _X0) // MOVSS (SP.p), X0 + self.call_c(_F_f32toa) // CALL_C f64toa + self.Emit("ADDQ" , _AX, _RL) // ADDQ AX, RL +} + +func (self *_Assembler) _asm_OP_f64(_ *_Instr) { + self.check_size(32) + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("MOVQ" , jit.Imm(_FM_exp64), _CX) // MOVQ $_FM_exp64, CX + self.Emit("ANDQ" , _CX, _AX) // ANDQ CX, AX + self.Emit("XORQ" , _CX, _AX) // XORQ CX, AX + self.Sjmp("JZ" , _LB_error_nan_or_infinite) // JZ _error_nan_or_infinite + self.save_c() // SAVE $C_regs + self.rbuf_di() // MOVQ RP, DI + self.Emit("MOVSD" , jit.Ptr(_SP_p, 0), _X0) // MOVSD (SP.p), X0 + self.call_c(_F_f64toa) // CALL_C f64toa + self.Emit("ADDQ" , _AX, _RL) // ADDQ AX, RL +} + +func (self *_Assembler) _asm_OP_str(_ *_Instr) { + self.encode_string(false) +} + +func (self *_Assembler) _asm_OP_bin(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_SP_p, 8), _AX) // MOVQ 8(SP.p), AX + self.Emit("ADDQ", jit.Imm(2), _AX) // ADDQ $2, AX + self.Emit("MOVQ", jit.Imm(_IM_mulv), _CX) // MOVQ $_MF_mulv, CX + self.Emit("MOVQ", _DX, _BX) // MOVQ DX, BX + self.From("MULQ", _CX) // MULQ CX + self.Emit("LEAQ", jit.Sib(_DX, _DX, 1, 1), _AX) // LEAQ 1(DX)(DX), AX + self.Emit("ORQ" , jit.Imm(2), _AX) // ORQ $2, AX + self.Emit("MOVQ", _BX, _DX) // MOVQ BX, DX + self.check_size_r(_AX, 0) // SIZE AX + self.add_char('"') // CHAR $'"' + self.Emit("MOVQ", _ARG_rb, _DI) // MOVQ rb<>+0(FP), DI + self.Emit("MOVQ", _RL, jit.Ptr(_DI, 8)) // MOVQ SI, 8(DI) + self.Emit("MOVQ", _SP_p, _SI) // MOVQ SP.p, SI + + /* check for AVX2 support */ + if !cpu.HasAVX2 { + self.Emit("XORL", _DX, _DX) // XORL DX, DX + } else { + self.Emit("MOVL", jit.Imm(_MODE_AVX2), _DX) // MOVL $_MODE_AVX2, DX + } + + /* call the encoder */ + self.call_b64(_F_b64encode) // CALL b64encode + self.load_buffer_AX() // LOAD {buf} + self.add_char('"') // CHAR $'"' +} + +func (self *_Assembler) _asm_OP_quote(_ *_Instr) { + self.encode_string(true) +} + +func (self *_Assembler) _asm_OP_number(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _BX) // MOVQ (SP.p), BX + self.Emit("TESTQ", _BX, _BX) // TESTQ BX, BX + self.Sjmp("JZ" , "_empty_{n}") + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JNZ" , "_number_next_{n}") + self.Emit("MOVQ", jit.Imm(int64(panicNilPointerOfNonEmptyString)), _AX) + self.Sjmp("JMP", _LB_panic) + self.Link("_number_next_{n}") + self.call_go(_F_isValidNumber) // CALL_GO isValidNumber + self.Emit("CMPB" , _AX, jit.Imm(0)) // CMPB AX, $0 + self.Sjmp("JE" , _LB_error_invalid_number) // JE _error_invalid_number + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _BX) // MOVQ (SP.p), BX + self.check_size_r(_BX, 0) // SIZE BX + self.Emit("LEAQ" , jit.Sib(_RP, _RL, 1, 0), _AX) // LEAQ (RP)(RL), AX + self.Emit("ADDQ" , jit.Ptr(_SP_p, 8), _RL) // ADDQ 8(SP.p), RL + self.Emit("MOVQ", jit.Ptr(_SP_p, 0), _BX) // MOVOU (SP.p), BX + self.Emit("MOVQ", jit.Ptr(_SP_p, 8), _CX) // MOVOU X0, 8(SP) + self.call_go(_F_memmove) // CALL_GO memmove + self.Emit("MOVQ", _ARG_rb, _AX) // MOVQ rb<>+0(FP), AX + self.Emit("MOVQ", _RL, jit.Ptr(_AX, 8)) // MOVQ RL, 8(AX) + self.Sjmp("JMP" , "_done_{n}") // JMP _done_{n} + self.Link("_empty_{n}") // _empty_{n} + self.check_size(1) // SIZE $1 + self.add_char('0') // CHAR $'0' + self.Link("_done_{n}") // _done_{n}: +} + +func (self *_Assembler) _asm_OP_eface(_ *_Instr) { + self.prep_buffer_AX() // MOVE {buf}, AX + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _BX) // MOVQ (SP.p), BX + self.Emit("LEAQ" , jit.Ptr(_SP_p, 8), _CX) // LEAQ 8(SP.p), CX + self.Emit("MOVQ" , _ST, _DI) // MOVQ ST, DI + self.Emit("MOVQ" , _ARG_fv, _SI) // MOVQ fv, AX + self.call_encoder(_F_encodeTypedPointer) // CALL encodeTypedPointer + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error + self.load_buffer_AX() +} + +func (self *_Assembler) _asm_OP_iface(_ *_Instr) { + self.prep_buffer_AX() // MOVE {buf}, AX + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _CX) // MOVQ (SP.p), CX + self.Emit("MOVQ" , jit.Ptr(_CX, 8), _BX) // MOVQ 8(CX), BX + self.Emit("LEAQ" , jit.Ptr(_SP_p, 8), _CX) // LEAQ 8(SP.p), CX + self.Emit("MOVQ" , _ST, _DI) // MOVQ ST, DI + self.Emit("MOVQ" , _ARG_fv, _SI) // MOVQ fv, AX + self.call_encoder(_F_encodeTypedPointer) // CALL encodeTypedPointer + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error + self.load_buffer_AX() +} + +func (self *_Assembler) _asm_OP_byte(p *_Instr) { + self.check_size(1) + self.Emit("MOVB", jit.Imm(p.i64()), jit.Sib(_RP, _RL, 1, 0)) // MOVL p.vi(), (RP)(RL*1) + self.Emit("ADDQ", jit.Imm(1), _RL) // ADDQ $1, RL +} + +func (self *_Assembler) _asm_OP_text(p *_Instr) { + self.check_size(len(p.vs())) // SIZE ${len(p.vs())} + self.add_text(p.vs()) // TEXT ${p.vs()} +} + +func (self *_Assembler) _asm_OP_deref(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_SP_p, 0), _SP_p) // MOVQ (SP.p), SP.p +} + +func (self *_Assembler) _asm_OP_index(p *_Instr) { + self.Emit("MOVQ", jit.Imm(p.i64()), _AX) // MOVQ $p.vi(), AX + self.Emit("ADDQ", _AX, _SP_p) // ADDQ AX, SP.p +} + +func (self *_Assembler) _asm_OP_load(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_ST, 0), _AX) // MOVQ (ST), AX + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, -24), _SP_x) // MOVQ -24(ST)(AX), SP.x + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, -8), _SP_p) // MOVQ -8(ST)(AX), SP.p + self.Emit("MOVQ", jit.Sib(_ST, _AX, 1, 0), _SP_q) // MOVQ (ST)(AX), SP.q +} + +func (self *_Assembler) _asm_OP_save(_ *_Instr) { + self.save_state() +} + +func (self *_Assembler) _asm_OP_drop(_ *_Instr) { + self.drop_state(_StateSize) +} + +func (self *_Assembler) _asm_OP_drop_2(_ *_Instr) { + self.drop_state(_StateSize * 2) // DROP $(_StateSize * 2) + self.Emit("MOVOU", _X0, jit.Sib(_ST, _AX, 1, 56)) // MOVOU X0, 56(ST)(AX) +} + +func (self *_Assembler) _asm_OP_recurse(p *_Instr) { + self.prep_buffer_AX() // MOVE {buf}, (SP) + vt, pv := p.vp() + self.Emit("MOVQ", jit.Type(vt), _BX) // MOVQ $(type(p.vt())), BX + + /* check for indirection */ + if !rt.UnpackType(vt).Indirect() { + self.Emit("MOVQ", _SP_p, _CX) // MOVQ SP.p, CX + } else { + self.Emit("MOVQ", _SP_p, _VAR_vp) // MOVQ SP.p, VAR.vp + self.Emit("LEAQ", _VAR_vp, _CX) // LEAQ VAR.vp, CX + } + + /* call the encoder */ + self.Emit("MOVQ" , _ST, _DI) // MOVQ ST, DI + self.Emit("MOVQ" , _ARG_fv, _SI) // MOVQ $fv, SI + if pv { + self.Emit("BTCQ", jit.Imm(bitPointerValue), _SI) // BTCQ $1, SI + } + self.call_encoder(_F_encodeTypedPointer) // CALL encodeTypedPointer + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error + self.load_buffer_AX() +} + +func (self *_Assembler) _asm_OP_is_nil(p *_Instr) { + self.Emit("CMPQ", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPQ (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_nil_p1(p *_Instr) { + self.Emit("CMPQ", jit.Ptr(_SP_p, 8), jit.Imm(0)) // CMPQ 8(SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_1(p *_Instr) { + self.Emit("CMPB", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPB (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_2(p *_Instr) { + self.Emit("CMPW", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPW (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_4(p *_Instr) { + self.Emit("CMPL", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPL (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_8(p *_Instr) { + self.Emit("CMPQ", jit.Ptr(_SP_p, 0), jit.Imm(0)) // CMPQ (SP.p), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_is_zero_map(p *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _AX) // MOVQ (SP.p), AX + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Xjmp("JZ" , p.vi()) // JZ p.vi() + self.Emit("CMPQ" , jit.Ptr(_AX, 0), jit.Imm(0)) // CMPQ (AX), $0 + self.Xjmp("JE" , p.vi()) // JE p.vi() +} + +func (self *_Assembler) _asm_OP_goto(p *_Instr) { + self.Xjmp("JMP", p.vi()) +} + +func (self *_Assembler) _asm_OP_map_iter(p *_Instr) { + self.Emit("MOVQ" , jit.Type(p.vt()), _AX) // MOVQ $p.vt(), AX + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _BX) // MOVQ (SP.p), BX + self.Emit("MOVQ" , _ARG_fv, _CX) // MOVQ fv, CX + self.call_go(_F_iteratorStart) // CALL_GO iteratorStart + self.Emit("MOVQ" , _AX, _SP_q) // MOVQ AX, SP.q + self.Emit("MOVQ" , _BX, _ET) // MOVQ 32(SP), ET + self.Emit("MOVQ" , _CX, _EP) // MOVQ 40(SP), EP + self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET + self.Sjmp("JNZ" , _LB_error) // JNZ _error +} + +func (self *_Assembler) _asm_OP_map_stop(_ *_Instr) { + self.Emit("MOVQ", _SP_q, _AX) // MOVQ SP.q, AX + self.call_go(_F_iteratorStop) // CALL_GO iteratorStop + self.Emit("XORL", _SP_q, _SP_q) // XORL SP.q, SP.q +} + +func (self *_Assembler) _asm_OP_map_check_key(p *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_SP_q, 0), _SP_p) // MOVQ (SP.q), SP.p + self.Emit("TESTQ", _SP_p, _SP_p) // TESTQ SP.p, SP.p + self.Xjmp("JZ" , p.vi()) // JNZ p.vi() +} + +func (self *_Assembler) _asm_OP_map_write_key(p *_Instr) { + self.Emit("BTQ", jit.Imm(bitSortMapKeys), _ARG_fv) // BTQ ${SortMapKeys}, fv + self.Sjmp("JNC", "_unordered_key_{n}") // JNC _unordered_key_{n} + self.encode_string(false) // STR $false + self.Xjmp("JMP", p.vi()) // JMP ${p.vi()} + self.Link("_unordered_key_{n}") // _unordered_key_{n}: +} + +func (self *_Assembler) _asm_OP_map_value_next(_ *_Instr) { + self.Emit("MOVQ", jit.Ptr(_SP_q, 8), _SP_p) // MOVQ 8(SP.q), SP.p + self.Emit("MOVQ", _SP_q, _AX) // MOVQ SP.q, AX + self.call_go(_F_iteratorNext) // CALL_GO iteratorNext +} + +func (self *_Assembler) _asm_OP_slice_len(_ *_Instr) { + self.Emit("MOVQ" , jit.Ptr(_SP_p, 8), _SP_x) // MOVQ 8(SP.p), SP.x + self.Emit("MOVQ" , jit.Ptr(_SP_p, 0), _SP_p) // MOVQ (SP.p), SP.p + self.Emit("ORQ" , jit.Imm(1 << _S_init), _SP_f) // ORQ $(1<<_S_init), SP.f +} + +func (self *_Assembler) _asm_OP_slice_next(p *_Instr) { + self.Emit("TESTQ" , _SP_x, _SP_x) // TESTQ SP.x, SP.x + self.Xjmp("JZ" , p.vi()) // JZ p.vi() + self.Emit("SUBQ" , jit.Imm(1), _SP_x) // SUBQ $1, SP.x + self.Emit("BTRQ" , jit.Imm(_S_init), _SP_f) // BTRQ $_S_init, SP.f + self.Emit("LEAQ" , jit.Ptr(_SP_p, int64(p.vlen())), _AX) // LEAQ $(p.vlen())(SP.p), AX + self.Emit("CMOVQCC", _AX, _SP_p) // CMOVQNC AX, SP.p +} + +func (self *_Assembler) _asm_OP_marshal(p *_Instr) { + self.call_marshaler(_F_encodeJsonMarshaler, _T_json_Marshaler, p.vt()) +} + +func (self *_Assembler) _asm_OP_marshal_p(p *_Instr) { + if p.vk() != reflect.Ptr { + panic("marshal_p: invalid type") + } else { + self.call_marshaler_v(_F_encodeJsonMarshaler, _T_json_Marshaler, p.vt(), false) + } +} + +func (self *_Assembler) _asm_OP_marshal_text(p *_Instr) { + self.call_marshaler(_F_encodeTextMarshaler, _T_encoding_TextMarshaler, p.vt()) +} + +func (self *_Assembler) _asm_OP_marshal_text_p(p *_Instr) { + if p.vk() != reflect.Ptr { + panic("marshal_text_p: invalid type") + } else { + self.call_marshaler_v(_F_encodeTextMarshaler, _T_encoding_TextMarshaler, p.vt(), false) + } +} + +func (self *_Assembler) _asm_OP_cond_set(_ *_Instr) { + self.Emit("ORQ", jit.Imm(1 << _S_cond), _SP_f) // ORQ $(1<<_S_cond), SP.f +} + +func (self *_Assembler) _asm_OP_cond_testc(p *_Instr) { + self.Emit("BTRQ", jit.Imm(_S_cond), _SP_f) // BTRQ $_S_cond, SP.f + self.Xjmp("JC" , p.vi()) +} + +func (self *_Assembler) print_gc(i int, p1 *_Instr, p2 *_Instr) { + self.Emit("MOVQ", jit.Imm(int64(p2.op())), _CX) // MOVQ $(p2.op()), AX + self.Emit("MOVQ", jit.Imm(int64(p1.op())), _BX) // MOVQ $(p1.op()), BX + self.Emit("MOVQ", jit.Imm(int64(i)), _AX) // MOVQ $(i), CX + self.call_go(_F_println) +} + +var ( + _V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&_runtime_writeBarrier)))) + + _F_gcWriteBarrierAX = jit.Func(gcWriteBarrierAX) +) + +func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr) { + if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { + panic("rec contains AX!") + } + self.Emit("MOVQ", _V_writeBarrier, _BX) + self.Emit("CMPL", jit.Ptr(_BX, 0), jit.Imm(0)) + self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.xsave(_DI) + self.Emit("MOVQ", ptr, _AX) + self.Emit("LEAQ", rec, _DI) + self.Emit("MOVQ", _F_gcWriteBarrierAX, _BX) // MOVQ ${fn}, AX + self.Rjmp("CALL", _BX) + self.xload(_DI) + self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") + self.Emit("MOVQ", ptr, rec) + self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}") +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/encoder/compiler.go b/ihub/vendor/github.com/bytedance/sonic/encoder/compiler.go new file mode 100644 index 0000000..a949c90 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/encoder/compiler.go @@ -0,0 +1,885 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package encoder + +import ( + `fmt` + `reflect` + `strconv` + `strings` + `unsafe` + + `github.com/bytedance/sonic/internal/resolver` + `github.com/bytedance/sonic/internal/rt` + `github.com/bytedance/sonic/option` +) + +type _Op uint8 + +const ( + _OP_null _Op = iota + 1 + _OP_empty_arr + _OP_empty_obj + _OP_bool + _OP_i8 + _OP_i16 + _OP_i32 + _OP_i64 + _OP_u8 + _OP_u16 + _OP_u32 + _OP_u64 + _OP_f32 + _OP_f64 + _OP_str + _OP_bin + _OP_quote + _OP_number + _OP_eface + _OP_iface + _OP_byte + _OP_text + _OP_deref + _OP_index + _OP_load + _OP_save + _OP_drop + _OP_drop_2 + _OP_recurse + _OP_is_nil + _OP_is_nil_p1 + _OP_is_zero_1 + _OP_is_zero_2 + _OP_is_zero_4 + _OP_is_zero_8 + _OP_is_zero_map + _OP_goto + _OP_map_iter + _OP_map_stop + _OP_map_check_key + _OP_map_write_key + _OP_map_value_next + _OP_slice_len + _OP_slice_next + _OP_marshal + _OP_marshal_p + _OP_marshal_text + _OP_marshal_text_p + _OP_cond_set + _OP_cond_testc +) + +const ( + _INT_SIZE = 32 << (^uint(0) >> 63) + _PTR_SIZE = 32 << (^uintptr(0) >> 63) + _PTR_BYTE = unsafe.Sizeof(uintptr(0)) +) + +const ( + _MAX_ILBUF = 100000 // cutoff at 100k of IL instructions + _MAX_FIELDS = 50 // cutoff at 50 fields struct +) + +var _OpNames = [256]string { + _OP_null : "null", + _OP_empty_arr : "empty_arr", + _OP_empty_obj : "empty_obj", + _OP_bool : "bool", + _OP_i8 : "i8", + _OP_i16 : "i16", + _OP_i32 : "i32", + _OP_i64 : "i64", + _OP_u8 : "u8", + _OP_u16 : "u16", + _OP_u32 : "u32", + _OP_u64 : "u64", + _OP_f32 : "f32", + _OP_f64 : "f64", + _OP_str : "str", + _OP_bin : "bin", + _OP_quote : "quote", + _OP_number : "number", + _OP_eface : "eface", + _OP_iface : "iface", + _OP_byte : "byte", + _OP_text : "text", + _OP_deref : "deref", + _OP_index : "index", + _OP_load : "load", + _OP_save : "save", + _OP_drop : "drop", + _OP_drop_2 : "drop_2", + _OP_recurse : "recurse", + _OP_is_nil : "is_nil", + _OP_is_nil_p1 : "is_nil_p1", + _OP_is_zero_1 : "is_zero_1", + _OP_is_zero_2 : "is_zero_2", + _OP_is_zero_4 : "is_zero_4", + _OP_is_zero_8 : "is_zero_8", + _OP_is_zero_map : "is_zero_map", + _OP_goto : "goto", + _OP_map_iter : "map_iter", + _OP_map_stop : "map_stop", + _OP_map_check_key : "map_check_key", + _OP_map_write_key : "map_write_key", + _OP_map_value_next : "map_value_next", + _OP_slice_len : "slice_len", + _OP_slice_next : "slice_next", + _OP_marshal : "marshal", + _OP_marshal_p : "marshal_p", + _OP_marshal_text : "marshal_text", + _OP_marshal_text_p : "marshal_text_p", + _OP_cond_set : "cond_set", + _OP_cond_testc : "cond_testc", +} + +func (self _Op) String() string { + if ret := _OpNames[self]; ret != "" { + return ret + } else { + return "" + } +} + +func _OP_int() _Op { + switch _INT_SIZE { + case 32: return _OP_i32 + case 64: return _OP_i64 + default: panic("unsupported int size") + } +} + +func _OP_uint() _Op { + switch _INT_SIZE { + case 32: return _OP_u32 + case 64: return _OP_u64 + default: panic("unsupported uint size") + } +} + +func _OP_uintptr() _Op { + switch _PTR_SIZE { + case 32: return _OP_u32 + case 64: return _OP_u64 + default: panic("unsupported pointer size") + } +} + +func _OP_is_zero_ints() _Op { + switch _INT_SIZE { + case 32: return _OP_is_zero_4 + case 64: return _OP_is_zero_8 + default: panic("unsupported integer size") + } +} + +type _Instr struct { + u uint64 // union {op: 8, _: 8, vi: 48}, vi maybe int or len(str) + p unsafe.Pointer // maybe GoString.Ptr, or *GoType +} + +func packOp(op _Op) uint64 { + return uint64(op) << 56 +} + +func newInsOp(op _Op) _Instr { + return _Instr{u: packOp(op)} +} + +func newInsVi(op _Op, vi int) _Instr { + return _Instr{u: packOp(op) | rt.PackInt(vi)} +} + +func newInsVs(op _Op, vs string) _Instr { + return _Instr { + u: packOp(op) | rt.PackInt(len(vs)), + p: (*rt.GoString)(unsafe.Pointer(&vs)).Ptr, + } +} + +func newInsVt(op _Op, vt reflect.Type) _Instr { + return _Instr { + u: packOp(op), + p: unsafe.Pointer(rt.UnpackType(vt)), + } +} + +func newInsVp(op _Op, vt reflect.Type, pv bool) _Instr { + i := 0 + if pv { + i = 1 + } + return _Instr { + u: packOp(op) | rt.PackInt(i), + p: unsafe.Pointer(rt.UnpackType(vt)), + } +} + +func (self _Instr) op() _Op { + return _Op(self.u >> 56) +} + +func (self _Instr) vi() int { + return rt.UnpackInt(self.u) +} + +func (self _Instr) vf() uint8 { + return (*rt.GoType)(self.p).KindFlags +} + +func (self _Instr) vs() (v string) { + (*rt.GoString)(unsafe.Pointer(&v)).Ptr = self.p + (*rt.GoString)(unsafe.Pointer(&v)).Len = self.vi() + return +} + +func (self _Instr) vk() reflect.Kind { + return (*rt.GoType)(self.p).Kind() +} + +func (self _Instr) vt() reflect.Type { + return (*rt.GoType)(self.p).Pack() +} + +func (self _Instr) vp() (vt reflect.Type, pv bool) { + return (*rt.GoType)(self.p).Pack(), rt.UnpackInt(self.u) == 1 +} + +func (self _Instr) i64() int64 { + return int64(self.vi()) +} + +func (self _Instr) vlen() int { + return int((*rt.GoType)(self.p).Size) +} + +func (self _Instr) isBranch() bool { + switch self.op() { + case _OP_goto : fallthrough + case _OP_is_nil : fallthrough + case _OP_is_nil_p1 : fallthrough + case _OP_is_zero_1 : fallthrough + case _OP_is_zero_2 : fallthrough + case _OP_is_zero_4 : fallthrough + case _OP_is_zero_8 : fallthrough + case _OP_map_check_key : fallthrough + case _OP_map_write_key : fallthrough + case _OP_slice_next : fallthrough + case _OP_cond_testc : return true + default : return false + } +} + +func (self _Instr) disassemble() string { + switch self.op() { + case _OP_byte : return fmt.Sprintf("%-18s%s", self.op().String(), strconv.QuoteRune(rune(self.vi()))) + case _OP_text : return fmt.Sprintf("%-18s%s", self.op().String(), strconv.Quote(self.vs())) + case _OP_index : return fmt.Sprintf("%-18s%d", self.op().String(), self.vi()) + case _OP_recurse : fallthrough + case _OP_map_iter : fallthrough + case _OP_marshal : fallthrough + case _OP_marshal_p : fallthrough + case _OP_marshal_text : fallthrough + case _OP_marshal_text_p : return fmt.Sprintf("%-18s%s", self.op().String(), self.vt()) + case _OP_goto : fallthrough + case _OP_is_nil : fallthrough + case _OP_is_nil_p1 : fallthrough + case _OP_is_zero_1 : fallthrough + case _OP_is_zero_2 : fallthrough + case _OP_is_zero_4 : fallthrough + case _OP_is_zero_8 : fallthrough + case _OP_is_zero_map : fallthrough + case _OP_cond_testc : fallthrough + case _OP_map_check_key : fallthrough + case _OP_map_write_key : return fmt.Sprintf("%-18sL_%d", self.op().String(), self.vi()) + case _OP_slice_next : return fmt.Sprintf("%-18sL_%d, %s", self.op().String(), self.vi(), self.vt()) + default : return self.op().String() + } +} + +type ( + _Program []_Instr +) + +func (self _Program) pc() int { + return len(self) +} + +func (self _Program) tag(n int) { + if n >= _MaxStack { + panic("type nesting too deep") + } +} + +func (self _Program) pin(i int) { + v := &self[i] + v.u &= 0xffff000000000000 + v.u |= rt.PackInt(self.pc()) +} + +func (self _Program) rel(v []int) { + for _, i := range v { + self.pin(i) + } +} + +func (self *_Program) add(op _Op) { + *self = append(*self, newInsOp(op)) +} + +func (self *_Program) key(op _Op) { + *self = append(*self, + newInsVi(_OP_byte, '"'), + newInsOp(op), + newInsVi(_OP_byte, '"'), + ) +} + +func (self *_Program) int(op _Op, vi int) { + *self = append(*self, newInsVi(op, vi)) +} + +func (self *_Program) str(op _Op, vs string) { + *self = append(*self, newInsVs(op, vs)) +} + +func (self *_Program) rtt(op _Op, vt reflect.Type) { + *self = append(*self, newInsVt(op, vt)) +} + +func (self *_Program) vp(op _Op, vt reflect.Type, pv bool) { + *self = append(*self, newInsVp(op, vt, pv)) +} + +func (self _Program) disassemble() string { + nb := len(self) + tab := make([]bool, nb + 1) + ret := make([]string, 0, nb + 1) + + /* prescan to get all the labels */ + for _, ins := range self { + if ins.isBranch() { + tab[ins.vi()] = true + } + } + + /* disassemble each instruction */ + for i, ins := range self { + if !tab[i] { + ret = append(ret, "\t" + ins.disassemble()) + } else { + ret = append(ret, fmt.Sprintf("L_%d:\n\t%s", i, ins.disassemble())) + } + } + + /* add the last label, if needed */ + if tab[nb] { + ret = append(ret, fmt.Sprintf("L_%d:", nb)) + } + + /* add an "end" indicator, and join all the strings */ + return strings.Join(append(ret, "\tend"), "\n") +} + +type _Compiler struct { + opts option.CompileOptions + pv bool + tab map[reflect.Type]bool + rec map[reflect.Type]uint8 +} + +func newCompiler() *_Compiler { + return &_Compiler { + opts: option.DefaultCompileOptions(), + tab: map[reflect.Type]bool{}, + rec: map[reflect.Type]uint8{}, + } +} + +func (self *_Compiler) apply(opts option.CompileOptions) *_Compiler { + self.opts = opts + if self.opts.RecursiveDepth > 0 { + self.rec = map[reflect.Type]uint8{} + } + return self +} + +func (self *_Compiler) rescue(ep *error) { + if val := recover(); val != nil { + if err, ok := val.(error); ok { + *ep = err + } else { + panic(val) + } + } +} + +func (self *_Compiler) compile(vt reflect.Type, pv bool) (ret _Program, err error) { + defer self.rescue(&err) + self.compileOne(&ret, 0, vt, pv) + return +} + +func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type, pv bool) { + if self.tab[vt] { + p.vp(_OP_recurse, vt, pv) + } else { + self.compileRec(p, sp, vt, pv) + } +} + +func (self *_Compiler) compileRec(p *_Program, sp int, vt reflect.Type, pv bool) { + pr := self.pv + pt := reflect.PtrTo(vt) + + /* check for addressable `json.Marshaler` with pointer receiver */ + if pv && pt.Implements(jsonMarshalerType) { + p.rtt(_OP_marshal_p, pt) + return + } + + /* check for `json.Marshaler` */ + if vt.Implements(jsonMarshalerType) { + self.compileMarshaler(p, _OP_marshal, vt, jsonMarshalerType) + return + } + + /* check for addressable `encoding.TextMarshaler` with pointer receiver */ + if pv && pt.Implements(encodingTextMarshalerType) { + p.rtt(_OP_marshal_text_p, pt) + return + } + + /* check for `encoding.TextMarshaler` */ + if vt.Implements(encodingTextMarshalerType) { + self.compileMarshaler(p, _OP_marshal_text, vt, encodingTextMarshalerType) + return + } + + /* enter the recursion, and compile the type */ + self.pv = pv + self.tab[vt] = true + self.compileOps(p, sp, vt) + + /* exit the recursion */ + self.pv = pr + delete(self.tab, vt) +} + +func (self *_Compiler) compileOps(p *_Program, sp int, vt reflect.Type) { + switch vt.Kind() { + case reflect.Bool : p.add(_OP_bool) + case reflect.Int : p.add(_OP_int()) + case reflect.Int8 : p.add(_OP_i8) + case reflect.Int16 : p.add(_OP_i16) + case reflect.Int32 : p.add(_OP_i32) + case reflect.Int64 : p.add(_OP_i64) + case reflect.Uint : p.add(_OP_uint()) + case reflect.Uint8 : p.add(_OP_u8) + case reflect.Uint16 : p.add(_OP_u16) + case reflect.Uint32 : p.add(_OP_u32) + case reflect.Uint64 : p.add(_OP_u64) + case reflect.Uintptr : p.add(_OP_uintptr()) + case reflect.Float32 : p.add(_OP_f32) + case reflect.Float64 : p.add(_OP_f64) + case reflect.String : self.compileString (p, vt) + case reflect.Array : self.compileArray (p, sp, vt.Elem(), vt.Len()) + case reflect.Interface : self.compileInterface (p, vt) + case reflect.Map : self.compileMap (p, sp, vt) + case reflect.Ptr : self.compilePtr (p, sp, vt.Elem()) + case reflect.Slice : self.compileSlice (p, sp, vt.Elem()) + case reflect.Struct : self.compileStruct (p, sp, vt) + default : panic (error_type(vt)) + } +} + +func (self *_Compiler) compileNil(p *_Program, sp int, vt reflect.Type, nil_op _Op, fn func(*_Program, int, reflect.Type)) { + x := p.pc() + p.add(_OP_is_nil) + fn(p, sp, vt) + e := p.pc() + p.add(_OP_goto) + p.pin(x) + p.add(nil_op) + p.pin(e) +} + +func (self *_Compiler) compilePtr(p *_Program, sp int, vt reflect.Type) { + self.compileNil(p, sp, vt, _OP_null, self.compilePtrBody) +} + +func (self *_Compiler) compilePtrBody(p *_Program, sp int, vt reflect.Type) { + p.tag(sp) + p.add(_OP_save) + p.add(_OP_deref) + self.compileOne(p, sp + 1, vt, true) + p.add(_OP_drop) +} + +func (self *_Compiler) compileMap(p *_Program, sp int, vt reflect.Type) { + self.compileNil(p, sp, vt, _OP_empty_obj, self.compileMapBody) +} + +func (self *_Compiler) compileMapBody(p *_Program, sp int, vt reflect.Type) { + p.tag(sp + 1) + p.int(_OP_byte, '{') + p.add(_OP_save) + p.rtt(_OP_map_iter, vt) + p.add(_OP_save) + i := p.pc() + p.add(_OP_map_check_key) + u := p.pc() + p.add(_OP_map_write_key) + self.compileMapBodyKey(p, vt.Key()) + p.pin(u) + p.int(_OP_byte, ':') + p.add(_OP_map_value_next) + self.compileOne(p, sp + 2, vt.Elem(), false) + j := p.pc() + p.add(_OP_map_check_key) + p.int(_OP_byte, ',') + v := p.pc() + p.add(_OP_map_write_key) + self.compileMapBodyKey(p, vt.Key()) + p.pin(v) + p.int(_OP_byte, ':') + p.add(_OP_map_value_next) + self.compileOne(p, sp + 2, vt.Elem(), false) + p.int(_OP_goto, j) + p.pin(i) + p.pin(j) + p.add(_OP_map_stop) + p.add(_OP_drop_2) + p.int(_OP_byte, '}') +} + +func (self *_Compiler) compileMapBodyKey(p *_Program, vk reflect.Type) { + if !vk.Implements(encodingTextMarshalerType) { + self.compileMapBodyTextKey(p, vk) + } else { + self.compileMapBodyUtextKey(p, vk) + } +} + +func (self *_Compiler) compileMapBodyTextKey(p *_Program, vk reflect.Type) { + switch vk.Kind() { + case reflect.Invalid : panic("map key is nil") + case reflect.Bool : p.key(_OP_bool) + case reflect.Int : p.key(_OP_int()) + case reflect.Int8 : p.key(_OP_i8) + case reflect.Int16 : p.key(_OP_i16) + case reflect.Int32 : p.key(_OP_i32) + case reflect.Int64 : p.key(_OP_i64) + case reflect.Uint : p.key(_OP_uint()) + case reflect.Uint8 : p.key(_OP_u8) + case reflect.Uint16 : p.key(_OP_u16) + case reflect.Uint32 : p.key(_OP_u32) + case reflect.Uint64 : p.key(_OP_u64) + case reflect.Uintptr : p.key(_OP_uintptr()) + case reflect.Float32 : p.key(_OP_f32) + case reflect.Float64 : p.key(_OP_f64) + case reflect.String : self.compileString(p, vk) + default : panic(error_type(vk)) + } +} + +func (self *_Compiler) compileMapBodyUtextKey(p *_Program, vk reflect.Type) { + if vk.Kind() != reflect.Ptr { + p.rtt(_OP_marshal_text, vk) + } else { + self.compileMapBodyUtextPtr(p, vk) + } +} + +func (self *_Compiler) compileMapBodyUtextPtr(p *_Program, vk reflect.Type) { + i := p.pc() + p.add(_OP_is_nil) + p.rtt(_OP_marshal_text, vk) + j := p.pc() + p.add(_OP_goto) + p.pin(i) + p.str(_OP_text, "\"\"") + p.pin(j) +} + +func (self *_Compiler) compileSlice(p *_Program, sp int, vt reflect.Type) { + self.compileNil(p, sp, vt, _OP_empty_arr, self.compileSliceBody) +} + +func (self *_Compiler) compileSliceBody(p *_Program, sp int, vt reflect.Type) { + if isSimpleByte(vt) { + p.add(_OP_bin) + } else { + self.compileSliceArray(p, sp, vt) + } +} + +func (self *_Compiler) compileSliceArray(p *_Program, sp int, vt reflect.Type) { + p.tag(sp) + p.int(_OP_byte, '[') + p.add(_OP_save) + p.add(_OP_slice_len) + i := p.pc() + p.rtt(_OP_slice_next, vt) + self.compileOne(p, sp + 1, vt, true) + j := p.pc() + p.rtt(_OP_slice_next, vt) + p.int(_OP_byte, ',') + self.compileOne(p, sp + 1, vt, true) + p.int(_OP_goto, j) + p.pin(i) + p.pin(j) + p.add(_OP_drop) + p.int(_OP_byte, ']') +} + +func (self *_Compiler) compileArray(p *_Program, sp int, vt reflect.Type, nb int) { + p.tag(sp) + p.int(_OP_byte, '[') + p.add(_OP_save) + + /* first item */ + if nb != 0 { + self.compileOne(p, sp + 1, vt, self.pv) + p.add(_OP_load) + } + + /* remaining items */ + for i := 1; i < nb; i++ { + p.int(_OP_byte, ',') + p.int(_OP_index, i * int(vt.Size())) + self.compileOne(p, sp + 1, vt, self.pv) + p.add(_OP_load) + } + + /* end of array */ + p.add(_OP_drop) + p.int(_OP_byte, ']') +} + +func (self *_Compiler) compileString(p *_Program, vt reflect.Type) { + if vt != jsonNumberType { + p.add(_OP_str) + } else { + p.add(_OP_number) + } +} + +func (self *_Compiler) compileStruct(p *_Program, sp int, vt reflect.Type) { + if sp >= self.opts.MaxInlineDepth || p.pc() >= _MAX_ILBUF || (sp > 0 && vt.NumField() >= _MAX_FIELDS) { + p.vp(_OP_recurse, vt, self.pv) + if self.opts.RecursiveDepth > 0 { + if self.pv { + self.rec[vt] = 1 + } else { + self.rec[vt] = 0 + } + } + } else { + self.compileStructBody(p, sp, vt) + } +} + +func (self *_Compiler) compileStructBody(p *_Program, sp int, vt reflect.Type) { + p.tag(sp) + p.int(_OP_byte, '{') + p.add(_OP_save) + p.add(_OP_cond_set) + + /* compile each field */ + for _, fv := range resolver.ResolveStruct(vt) { + var s []int + var o resolver.Offset + + /* "omitempty" for arrays */ + if fv.Type.Kind() == reflect.Array { + if fv.Type.Len() == 0 && (fv.Opts & resolver.F_omitempty) != 0 { + continue + } + } + + /* index to the field */ + for _, o = range fv.Path { + if p.int(_OP_index, int(o.Size)); o.Kind == resolver.F_deref { + s = append(s, p.pc()) + p.add(_OP_is_nil) + p.add(_OP_deref) + } + } + + /* check for "omitempty" option */ + if fv.Type.Kind() != reflect.Struct && fv.Type.Kind() != reflect.Array && (fv.Opts & resolver.F_omitempty) != 0 { + s = append(s, p.pc()) + self.compileStructFieldZero(p, fv.Type) + } + + /* add the comma if not the first element */ + i := p.pc() + p.add(_OP_cond_testc) + p.int(_OP_byte, ',') + p.pin(i) + + /* compile the key and value */ + ft := fv.Type + p.str(_OP_text, Quote(fv.Name) + ":") + + /* check for "stringnize" option */ + if (fv.Opts & resolver.F_stringize) == 0 { + self.compileOne(p, sp + 1, ft, self.pv) + } else { + self.compileStructFieldStr(p, sp + 1, ft) + } + + /* patch the skipping jumps and reload the struct pointer */ + p.rel(s) + p.add(_OP_load) + } + + /* end of object */ + p.add(_OP_drop) + p.int(_OP_byte, '}') +} + +func (self *_Compiler) compileStructFieldStr(p *_Program, sp int, vt reflect.Type) { + pc := -1 + ft := vt + sv := false + + /* dereference the pointer if needed */ + if ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + + /* check if it can be stringized */ + switch ft.Kind() { + case reflect.Bool : sv = true + case reflect.Int : sv = true + case reflect.Int8 : sv = true + case reflect.Int16 : sv = true + case reflect.Int32 : sv = true + case reflect.Int64 : sv = true + case reflect.Uint : sv = true + case reflect.Uint8 : sv = true + case reflect.Uint16 : sv = true + case reflect.Uint32 : sv = true + case reflect.Uint64 : sv = true + case reflect.Uintptr : sv = true + case reflect.Float32 : sv = true + case reflect.Float64 : sv = true + case reflect.String : sv = true + } + + /* if it's not, ignore the "string" and follow the regular path */ + if !sv { + self.compileOne(p, sp, vt, self.pv) + return + } + + /* dereference the pointer */ + if vt.Kind() == reflect.Ptr { + pc = p.pc() + vt = vt.Elem() + p.add(_OP_is_nil) + p.add(_OP_deref) + } + + /* special case of a double-quoted string */ + if ft != jsonNumberType && ft.Kind() == reflect.String { + p.add(_OP_quote) + } else { + self.compileStructFieldQuoted(p, sp, vt) + } + + /* the "null" case of the pointer */ + if pc != -1 { + e := p.pc() + p.add(_OP_goto) + p.pin(pc) + p.add(_OP_null) + p.pin(e) + } +} + +func (self *_Compiler) compileStructFieldZero(p *_Program, vt reflect.Type) { + switch vt.Kind() { + case reflect.Bool : p.add(_OP_is_zero_1) + case reflect.Int : p.add(_OP_is_zero_ints()) + case reflect.Int8 : p.add(_OP_is_zero_1) + case reflect.Int16 : p.add(_OP_is_zero_2) + case reflect.Int32 : p.add(_OP_is_zero_4) + case reflect.Int64 : p.add(_OP_is_zero_8) + case reflect.Uint : p.add(_OP_is_zero_ints()) + case reflect.Uint8 : p.add(_OP_is_zero_1) + case reflect.Uint16 : p.add(_OP_is_zero_2) + case reflect.Uint32 : p.add(_OP_is_zero_4) + case reflect.Uint64 : p.add(_OP_is_zero_8) + case reflect.Uintptr : p.add(_OP_is_nil) + case reflect.Float32 : p.add(_OP_is_zero_4) + case reflect.Float64 : p.add(_OP_is_zero_8) + case reflect.String : p.add(_OP_is_nil_p1) + case reflect.Interface : p.add(_OP_is_nil_p1) + case reflect.Map : p.add(_OP_is_zero_map) + case reflect.Ptr : p.add(_OP_is_nil) + case reflect.Slice : p.add(_OP_is_nil_p1) + default : panic(error_type(vt)) + } +} + +func (self *_Compiler) compileStructFieldQuoted(p *_Program, sp int, vt reflect.Type) { + p.int(_OP_byte, '"') + self.compileOne(p, sp, vt, self.pv) + p.int(_OP_byte, '"') +} + +func (self *_Compiler) compileInterface(p *_Program, vt reflect.Type) { + x := p.pc() + p.add(_OP_is_nil_p1) + + /* iface and efaces are different */ + if vt.NumMethod() == 0 { + p.add(_OP_eface) + } else { + p.add(_OP_iface) + } + + /* the "null" value */ + e := p.pc() + p.add(_OP_goto) + p.pin(x) + p.add(_OP_null) + p.pin(e) +} + +func (self *_Compiler) compileMarshaler(p *_Program, op _Op, vt reflect.Type, mt reflect.Type) { + pc := p.pc() + vk := vt.Kind() + + /* direct receiver */ + if vk != reflect.Ptr { + p.rtt(op, vt) + return + } + + /* value receiver with a pointer type, check for nil before calling the marshaler */ + p.add(_OP_is_nil) + p.rtt(op, vt) + i := p.pc() + p.add(_OP_goto) + p.pin(pc) + p.add(_OP_null) + p.pin(i) +} diff --git a/ihub/vendor/github.com/bytedance/sonic/encoder/debug_go116.go b/ihub/vendor/github.com/bytedance/sonic/encoder/debug_go116.go new file mode 100644 index 0000000..4bc9c15 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/encoder/debug_go116.go @@ -0,0 +1,66 @@ +// +build go1.15,!go1.17 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package encoder + +import ( + `os` + `strings` + `runtime` + `runtime/debug` + + `github.com/bytedance/sonic/internal/jit` +) + +var ( + debugSyncGC = os.Getenv("SONIC_SYNC_GC") != "" + debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == "" +) + +var ( + _Instr_End _Instr = newInsOp(_OP_null) + + _F_gc = jit.Func(runtime.GC) + _F_force_gc = jit.Func(debug.FreeOSMemory) + _F_println = jit.Func(println_wrapper) +) + +func println_wrapper(i int, op1 int, op2 int){ + println(i, " Intrs ", op1, _OpNames[op1], "next: ", op2, _OpNames[op2]) +} + +func (self *_Assembler) force_gc() { + self.call_go(_F_gc) + self.call_go(_F_force_gc) +} + +func (self *_Assembler) debug_instr(i int, v *_Instr) { + if debugSyncGC { + if (i+1 == len(self.p)) { + self.print_gc(i, v, &_Instr_End) + } else { + next := &(self.p[i+1]) + self.print_gc(i, v, next) + name := _OpNames[next.op()] + if strings.Contains(name, "save") { + return + } + } + self.force_gc() + } +} diff --git a/ihub/vendor/github.com/bytedance/sonic/encoder/debug_go117.go b/ihub/vendor/github.com/bytedance/sonic/encoder/debug_go117.go new file mode 100644 index 0000000..e1016de --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/encoder/debug_go117.go @@ -0,0 +1,205 @@ +// +build go1.17,!go1.21 + +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package encoder + +import ( + `fmt` + `os` + `runtime` + `strings` + `unsafe` + + `github.com/bytedance/sonic/internal/jit` + `github.com/twitchyliquid64/golang-asm/obj` +) + +const _FP_debug = 128 + +var ( + debugSyncGC = os.Getenv("SONIC_SYNC_GC") != "" + debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == "" + debugCheckPtr = os.Getenv("SONIC_CHECK_POINTER") != "" +) + +var ( + _Instr_End = newInsOp(_OP_is_nil) + + _F_gc = jit.Func(gc) + _F_println = jit.Func(println_wrapper) + _F_print = jit.Func(print) +) + +func (self *_Assembler) dsave(r ...obj.Addr) { + for i, v := range r { + if i > _FP_debug / 8 - 1 { + panic("too many registers to save") + } else { + self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs + _FP_saves + _FP_locals + int64(i) * 8)) + } + } +} + +func (self *_Assembler) dload(r ...obj.Addr) { + for i, v := range r { + if i > _FP_debug / 8 - 1 { + panic("too many registers to load") + } else { + self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs + _FP_saves + _FP_locals + int64(i) * 8), v) + } + } +} + +func println_wrapper(i int, op1 int, op2 int){ + println(i, " Intrs ", op1, _OpNames[op1], "next: ", op2, _OpNames[op2]) +} + +func print(i int){ + println(i) +} + +func gc() { + if !debugSyncGC { + return + } + runtime.GC() + // debug.FreeOSMemory() +} + +func (self *_Assembler) dcall(fn obj.Addr) { + self.Emit("MOVQ", fn, _R10) // MOVQ ${fn}, R10 + self.Rjmp("CALL", _R10) // CALL R10 +} + +func (self *_Assembler) debug_gc() { + if !debugSyncGC { + return + } + self.dsave(_REG_debug...) + self.dcall(_F_gc) + self.dload(_REG_debug...) +} + +func (self *_Assembler) debug_instr(i int, v *_Instr) { + if debugSyncGC { + if i+1 == len(self.p) { + self.print_gc(i, v, &_Instr_End) + } else { + next := &(self.p[i+1]) + self.print_gc(i, v, next) + name := _OpNames[next.op()] + if strings.Contains(name, "save") { + return + } + } + // self.debug_gc() + } +} + +//go:noescape +//go:linkname checkptrBase runtime.checkptrBase +func checkptrBase(p unsafe.Pointer) uintptr + +//go:noescape +//go:linkname findObject runtime.findObject +func findObject(p, refBase, refOff uintptr) (base uintptr, s unsafe.Pointer, objIndex uintptr) + +var ( + _F_checkptr = jit.Func(checkptr) + _F_printptr = jit.Func(printptr) +) + +var ( + _R10 = jit.Reg("R10") +) +var _REG_debug = []obj.Addr { + jit.Reg("AX"), + jit.Reg("BX"), + jit.Reg("CX"), + jit.Reg("DX"), + jit.Reg("DI"), + jit.Reg("SI"), + jit.Reg("BP"), + jit.Reg("SP"), + jit.Reg("R8"), + jit.Reg("R9"), + jit.Reg("R10"), + jit.Reg("R11"), + jit.Reg("R12"), + jit.Reg("R13"), + jit.Reg("R14"), + jit.Reg("R15"), +} + +func checkptr(ptr uintptr) { + if ptr == 0 { + return + } + fmt.Printf("pointer: %x\n", ptr) + f := checkptrBase(unsafe.Pointer(uintptr(ptr))) + if f == 0 { + fmt.Printf("! unknown-based pointer: %x\n", ptr) + } else if f == 1 { + fmt.Printf("! stack pointer: %x\n", ptr) + } else { + fmt.Printf("base: %x\n", f) + } + findobj(ptr) +} + +func findobj(ptr uintptr) { + base, s, objIndex := findObject(ptr, 0, 0) + if s != nil && base == 0 { + fmt.Printf("! invalid pointer: %x\n", ptr) + } + fmt.Printf("objIndex: %d\n", objIndex) +} + +func (self *_Assembler) check_ptr(ptr obj.Addr, lea bool) { + if !debugCheckPtr { + return + } + + self.dsave(_REG_debug...) + if lea { + self.Emit("LEAQ", ptr, _R10) + } else { + self.Emit("MOVQ", ptr, _R10) + } + self.Emit("MOVQ", _R10, jit.Ptr(_SP, 0)) + self.dcall(_F_checkptr) + self.dload(_REG_debug...) +} + +func printptr(i int, ptr uintptr) { + fmt.Printf("[%d] ptr: %x\n", i, ptr) +} + +func (self *_Assembler) print_ptr(i int, ptr obj.Addr, lea bool) { + self.dsave(_REG_debug...) + if lea { + self.Emit("LEAQ", ptr, _R10) + } else { + self.Emit("MOVQ", ptr, _R10) + } + + self.Emit("MOVQ", jit.Imm(int64(i)), _AX) + self.Emit("MOVQ", _R10, _BX) + self.dcall(_F_printptr) + self.dload(_REG_debug...) +} \ No newline at end of file diff --git a/ihub/vendor/github.com/bytedance/sonic/encoder/encoder.go b/ihub/vendor/github.com/bytedance/sonic/encoder/encoder.go new file mode 100644 index 0000000..7a13301 --- /dev/null +++ b/ihub/vendor/github.com/bytedance/sonic/encoder/encoder.go @@ -0,0 +1,311 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package encoder + +import ( + `bytes` + `encoding/json` + `reflect` + `runtime` + + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` + `github.com/bytedance/sonic/utf8` + `github.com/bytedance/sonic/option` +) + +// Options is a set of encoding options. +type Options uint64 + +const ( + bitSortMapKeys = iota + bitEscapeHTML + bitCompactMarshaler + bitNoQuoteTextMarshaler + bitNoNullSliceOrMap + bitValidateString + + // used for recursive compile + bitPointerValue = 63 +) + +const ( + // SortMapKeys indicates that the keys of a map needs to be sorted + // before serializing into JSON. + // WARNING: This hurts performance A LOT, USE WITH CARE. + SortMapKeys Options = 1 << bitSortMapKeys + + // EscapeHTML indicates encoder to escape all HTML characters + // after serializing into JSON (see https://pkg.go.dev/encoding/json#HTMLEscape). + // WARNING: This hurts performance A LOT, USE WITH CARE. + EscapeHTML Options = 1 << bitEscapeHTML + + // CompactMarshaler indicates that the output JSON from json.Marshaler + // is always compact and needs no validation + CompactMarshaler Options = 1 << bitCompactMarshaler + + // NoQuoteTextMarshaler indicates that the output text from encoding.TextMarshaler + // is always escaped string and needs no quoting + NoQuoteTextMarshaler Options = 1 << bitNoQuoteTextMarshaler + + // NoNullSliceOrMap indicates all empty Array or Object are encoded as '[]' or '{}', + // instead of 'null' + NoNullSliceOrMap Options = 1 << bitNoNullSliceOrMap + + // ValidateString indicates that encoder should validate the input string + // before encoding it into JSON. + ValidateString Options = 1 << bitValidateString + + // CompatibleWithStd is used to be compatible with std encoder. + CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler +) + +// Encoder represents a specific set of encoder configurations. +type Encoder struct { + Opts Options + prefix string + indent string +} + +// Encode returns the JSON encoding of v. +func (self *Encoder) Encode(v interface{}) ([]byte, error) { + if self.indent != "" || self.prefix != "" { + return EncodeIndented(v, self.prefix, self.indent, self.Opts) + } + return Encode(v, self.Opts) +} + +// SortKeys enables the SortMapKeys option. +func (self *Encoder) SortKeys() *Encoder { + self.Opts |= SortMapKeys + return self +} + +// SetEscapeHTML specifies if option EscapeHTML opens +func (self *Encoder) SetEscapeHTML(f bool) { + if f { + self.Opts |= EscapeHTML + } else { + self.Opts &= ^EscapeHTML + } +} + +// SetValidateString specifies if option ValidateString opens +func (self *Encoder) SetValidateString(f bool) { + if f { + self.Opts |= ValidateString + } else { + self.Opts &= ^ValidateString + } +} + +// SetCompactMarshaler specifies if option CompactMarshaler opens +func (self *Encoder) SetCompactMarshaler(f bool) { + if f { + self.Opts |= CompactMarshaler + } else { + self.Opts &= ^CompactMarshaler + } +} + +// SetNoQuoteTextMarshaler specifies if option NoQuoteTextMarshaler opens +func (self *Encoder) SetNoQuoteTextMarshaler(f bool) { + if f { + self.Opts |= NoQuoteTextMarshaler + } else { + self.Opts &= ^NoQuoteTextMarshaler + } +} + +// SetIndent instructs the encoder to format each subsequent encoded +// value as if indented by the package-level function EncodeIndent(). +// Calling SetIndent("", "") disables indentation. +func (enc *Encoder) SetIndent(prefix, indent string) { + enc.prefix = prefix + enc.indent = indent +} + +// Quote returns the JSON-quoted version of s. +func Quote(s string) string { + var n int + var p []byte + + /* check for empty string */ + if s == "" { + return `""` + } + + /* allocate space for result */ + n = len(s) + 2 + p = make([]byte, 0, n) + + /* call the encoder */ + _ = encodeString(&p, s) + return rt.Mem2Str(p) +} + +// Encode returns the JSON encoding of val, encoded with opts. +func Encode(val interface{}, opts Options) ([]byte, error) { + buf := newBytes() + err := EncodeInto(&buf, val, opts) + + /* check for errors */ + if err != nil { + freeBytes(buf) + return nil, err + } + + if opts & EscapeHTML != 0 || opts & ValidateString != 0 { + return buf, nil + } + + /* make a copy of the result */ + ret := make([]byte, len(buf)) + copy(ret, buf) + + freeBytes(buf) + /* return the buffer into pool */ + return ret, nil +} + +// EncodeInto is like Encode but uses a user-supplied buffer instead of allocating +// a new one. +func EncodeInto(buf *[]byte, val interface{}, opts Options) error { + stk := newStack() + efv := rt.UnpackEface(val) + err := encodeTypedPointer(buf, efv.Type, &efv.Value, stk, uint64(opts)) + + /* return the stack into pool */ + if err != nil { + resetStack(stk) + } + freeStack(stk) + + /* EscapeHTML needs to allocate a new buffer*/ + if opts & EscapeHTML != 0 { + dest := HTMLEscape(nil, *buf) + freeBytes(*buf) // free origin used buffer + *buf = dest + } + + if opts & ValidateString != 0 && !utf8.Validate(*buf) { + dest := utf8.CorrectWith(nil, *buf, `\ufffd`) + freeBytes(*buf) // free origin used buffer + *buf = dest + } + + /* avoid GC ahead */ + runtime.KeepAlive(buf) + runtime.KeepAlive(efv) + return err +} + +var typeByte = rt.UnpackType(reflect.TypeOf(byte(0))) + +// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 +// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 +// so that the JSON will be safe to embed inside HTML