...
1
16
17 package abi
18
19 import (
20 `fmt`
21 `reflect`
22 `sort`
23 `strings`
24
25 `github.com/bytedance/sonic/internal/rt`
26 )
27
28 type FunctionLayout struct {
29 FP uint32
30 Args []Parameter
31 Rets []Parameter
32 }
33
34 func (self FunctionLayout) String() string {
35 return self.formatFn()
36 }
37
38 func (self FunctionLayout) ArgSize() uint32 {
39 size := uintptr(0)
40 for _, arg := range self.Args {
41 size += arg.Type.Size()
42 }
43 return uint32(size)
44 }
45
46 type slot struct {
47 p bool
48 m uint32
49 }
50
51 func (self FunctionLayout) StackMap() *rt.StackMap {
52 var st []slot
53 var mb rt.StackMapBuilder
54
55
56 for _, v := range self.Args {
57 st = append(st, slot {
58 m: v.Mem,
59 p: v.IsPointer,
60 })
61 }
62
63
64 for _, v := range self.Rets {
65 if !v.InRegister {
66 st = append(st, slot {
67 m: v.Mem,
68 p: v.IsPointer,
69 })
70 }
71 }
72
73
74 sort.Slice(st, func(i int, j int) bool {
75 return st[i].m < st[j].m
76 })
77
78
79 for _, v := range st {
80 mb.AddField(v.p)
81 }
82
83
84 return mb.Build()
85 }
86
87 func (self FunctionLayout) formatFn() string {
88 fp := self.FP
89 return fmt.Sprintf("\n%#04x\nRets:\n%s\nArgs:\n%s", fp, self.formatSeq(self.Rets, &fp), self.formatSeq(self.Args, &fp))
90 }
91
92 func (self FunctionLayout) formatSeq(v []Parameter, fp *uint32) string {
93 nb := len(v)
94 mm := make([]string, 0, len(v))
95
96
97 for i := nb-1; i >=0; i-- {
98 *fp -= PtrSize
99 mm = append(mm, fmt.Sprintf("%#04x %s", *fp, v[i].String()))
100 }
101
102
103 return strings.Join(mm, "\n")
104 }
105
106 type Frame struct {
107 desc *FunctionLayout
108 locals []bool
109 ccall bool
110 }
111
112 func NewFrame(desc *FunctionLayout, locals []bool, ccall bool) Frame {
113 fr := Frame{}
114 fr.desc = desc
115 fr.locals = locals
116 fr.ccall = ccall
117 return fr
118 }
119
120 func (self *Frame) String() string {
121 out := self.desc.String()
122
123 off := -8
124 out += fmt.Sprintf("\n%#4x [Return PC]", off)
125 off -= 8
126 out += fmt.Sprintf("\n%#4x [RBP]", off)
127 off -= 8
128
129 for _, v := range ReservedRegs(self.ccall) {
130 out += fmt.Sprintf("\n%#4x [%v]", off, v)
131 off -= PtrSize
132 }
133
134 for _, b := range self.locals {
135 out += fmt.Sprintf("\n%#4x [%v]", off, b)
136 off -= PtrSize
137 }
138
139 return out
140 }
141
142 func (self *Frame) Prev() uint32 {
143 return self.Size() + PtrSize
144 }
145
146 func (self *Frame) Size() uint32 {
147 return uint32(self.Offs() + PtrSize)
148 }
149
150 func (self *Frame) Offs() uint32 {
151 return uint32(len(ReservedRegs(self.ccall)) * PtrSize + len(self.locals)*PtrSize)
152 }
153
154 func (self *Frame) ArgPtrs() *rt.StackMap {
155 return self.desc.StackMap()
156 }
157
158 func (self *Frame) LocalPtrs() *rt.StackMap {
159 var m rt.StackMapBuilder
160 for _, b := range self.locals {
161 m.AddFields(len(ReservedRegs(self.ccall)), b)
162 }
163 return m.Build()
164 }
165
166 func alignUp(n uint32, a int) uint32 {
167 return (uint32(n) + uint32(a) - 1) &^ (uint32(a) - 1)
168 }
169
170 func isPointer(vt reflect.Type) bool {
171 switch vt.Kind() {
172 case reflect.Bool : fallthrough
173 case reflect.Int : fallthrough
174 case reflect.Int8 : fallthrough
175 case reflect.Int16 : fallthrough
176 case reflect.Int32 : fallthrough
177 case reflect.Int64 : fallthrough
178 case reflect.Uint : fallthrough
179 case reflect.Uint8 : fallthrough
180 case reflect.Uint16 : fallthrough
181 case reflect.Uint32 : fallthrough
182 case reflect.Uint64 : fallthrough
183 case reflect.Float32 : fallthrough
184 case reflect.Float64 : fallthrough
185 case reflect.Uintptr : return false
186 case reflect.Chan : fallthrough
187 case reflect.Func : fallthrough
188 case reflect.Map : fallthrough
189 case reflect.Ptr : fallthrough
190 case reflect.UnsafePointer : return true
191 case reflect.Complex64 : fallthrough
192 case reflect.Complex128 : fallthrough
193 case reflect.Array : fallthrough
194 case reflect.Struct : panic("abi: unsupported types")
195 default : panic("abi: invalid value type")
196 }
197 }
View as plain text