123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /*
- * 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.
- */
- package abi
- import (
- `fmt`
- `reflect`
- `sort`
- `strings`
- `github.com/bytedance/sonic/internal/rt`
- )
- type FunctionLayout struct {
- FP uint32
- Args []Parameter
- Rets []Parameter
- }
- func (self FunctionLayout) String() string {
- return self.formatFn()
- }
- func (self FunctionLayout) ArgSize() uint32 {
- size := uintptr(0)
- for _, arg := range self.Args {
- size += arg.Type.Size()
- }
- return uint32(size)
- }
- type slot struct {
- p bool
- m uint32
- }
- func (self FunctionLayout) StackMap() *rt.StackMap {
- var st []slot
- var mb rt.StackMapBuilder
- /* add arguments */
- for _, v := range self.Args {
- st = append(st, slot {
- m: v.Mem,
- p: v.IsPointer,
- })
- }
- /* add stack-passed return values */
- for _, v := range self.Rets {
- if !v.InRegister {
- st = append(st, slot {
- m: v.Mem,
- p: v.IsPointer,
- })
- }
- }
- /* sort by memory offset */
- sort.Slice(st, func(i int, j int) bool {
- return st[i].m < st[j].m
- })
- /* add the bits */
- for _, v := range st {
- mb.AddField(v.p)
- }
- /* build the stack map */
- return mb.Build()
- }
- func (self FunctionLayout) formatFn() string {
- fp := self.FP
- return fmt.Sprintf("\n%#04x\nRets:\n%s\nArgs:\n%s", fp, self.formatSeq(self.Rets, &fp), self.formatSeq(self.Args, &fp))
- }
- func (self FunctionLayout) formatSeq(v []Parameter, fp *uint32) string {
- nb := len(v)
- mm := make([]string, 0, len(v))
- /* convert each part */
- for i := nb-1; i >=0; i-- {
- *fp -= PtrSize
- mm = append(mm, fmt.Sprintf("%#04x %s", *fp, v[i].String()))
- }
- /* join them together */
- return strings.Join(mm, "\n")
- }
- type Frame struct {
- desc *FunctionLayout
- locals []bool
- ccall bool
- }
- func NewFrame(desc *FunctionLayout, locals []bool, ccall bool) Frame {
- fr := Frame{}
- fr.desc = desc
- fr.locals = locals
- fr.ccall = ccall
- return fr
- }
- func (self *Frame) String() string {
- out := self.desc.String()
- off := -8
- out += fmt.Sprintf("\n%#4x [Return PC]", off)
- off -= 8
- out += fmt.Sprintf("\n%#4x [RBP]", off)
- off -= 8
- for _, v := range ReservedRegs(self.ccall) {
- out += fmt.Sprintf("\n%#4x [%v]", off, v)
- off -= PtrSize
- }
- for _, b := range self.locals {
- out += fmt.Sprintf("\n%#4x [%v]", off, b)
- off -= PtrSize
- }
- return out
- }
- func (self *Frame) Prev() uint32 {
- return self.Size() + PtrSize
- }
- func (self *Frame) Size() uint32 {
- return uint32(self.Offs() + PtrSize)
- }
- func (self *Frame) Offs() uint32 {
- return uint32(len(ReservedRegs(self.ccall)) * PtrSize + len(self.locals)*PtrSize)
- }
- func (self *Frame) ArgPtrs() *rt.StackMap {
- return self.desc.StackMap()
- }
- func (self *Frame) LocalPtrs() *rt.StackMap {
- var m rt.StackMapBuilder
- for _, b := range self.locals {
- m.AddFields(len(ReservedRegs(self.ccall)), b)
- }
- return m.Build()
- }
- func alignUp(n uint32, a int) uint32 {
- return (uint32(n) + uint32(a) - 1) &^ (uint32(a) - 1)
- }
- func isPointer(vt reflect.Type) bool {
- switch vt.Kind() {
- case reflect.Bool : fallthrough
- case reflect.Int : fallthrough
- case reflect.Int8 : fallthrough
- case reflect.Int16 : fallthrough
- case reflect.Int32 : fallthrough
- case reflect.Int64 : fallthrough
- case reflect.Uint : fallthrough
- case reflect.Uint8 : fallthrough
- case reflect.Uint16 : fallthrough
- case reflect.Uint32 : fallthrough
- case reflect.Uint64 : fallthrough
- case reflect.Float32 : fallthrough
- case reflect.Float64 : fallthrough
- case reflect.Uintptr : return false
- case reflect.Chan : fallthrough
- case reflect.Func : fallthrough
- case reflect.Map : fallthrough
- case reflect.Ptr : fallthrough
- case reflect.UnsafePointer : return true
- case reflect.Complex64 : fallthrough
- case reflect.Complex128 : fallthrough
- case reflect.Array : fallthrough
- case reflect.Struct : panic("abi: unsupported types")
- default : panic("abi: invalid value type")
- }
- }
|