podman

Форк
0
197 строк · 4.9 Кб
1
/*
2
 * Copyright 2022 ByteDance Inc.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
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
    /* add arguments */
56
    for _, v := range self.Args {
57
        st = append(st, slot {
58
            m: v.Mem,
59
            p: v.IsPointer,
60
        })
61
    }
62

63
    /* add stack-passed return values */
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
    /* sort by memory offset */
74
    sort.Slice(st, func(i int, j int) bool {
75
        return st[i].m < st[j].m
76
    })
77

78
    /* add the bits */
79
    for _, v := range st {
80
        mb.AddField(v.p)
81
    }
82

83
    /* build the stack map */
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
    /* convert each part */
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
    /* join them together */
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
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.