abi.go 4.9 KB

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