github.com/cloudwego/frugal@v0.1.15/internal/atm/abi/abi_legacy_amd64.go (about)

     1  // +build !go1.17
     2  
     3  /*
     4   * Copyright 2022 ByteDance Inc.
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   *     http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package abi
    20  
    21  import (
    22      `reflect`
    23  
    24      `github.com/cloudwego/iasm/x86_64`
    25  )
    26  
    27  func salloc(p []Parameter, sp uintptr, vt reflect.Type) (uintptr, []Parameter) {
    28      switch vt.Kind() {
    29          case reflect.Bool          : return sp + 8, append(p, mkStack(reflect.TypeOf(false), sp))
    30          case reflect.Int           : return sp + 8, append(p, mkStack(intType, sp))
    31          case reflect.Int8          : return sp + 8, append(p, mkStack(reflect.TypeOf(int8(0)), sp))
    32          case reflect.Int16         : return sp + 8, append(p, mkStack(reflect.TypeOf(int16(0)), sp))
    33          case reflect.Int32         : return sp + 8, append(p, mkStack(reflect.TypeOf(int32(0)), sp))
    34          case reflect.Int64         : return sp + 8, append(p, mkStack(reflect.TypeOf(int64(0)), sp))
    35          case reflect.Uint          : return sp + 8, append(p, mkStack(reflect.TypeOf(uint(0)), sp))
    36          case reflect.Uint8         : return sp + 8, append(p, mkStack(reflect.TypeOf(uint8(0)), sp))
    37          case reflect.Uint16        : return sp + 8, append(p, mkStack(reflect.TypeOf(uint16(0)), sp))
    38          case reflect.Uint32        : return sp + 8, append(p, mkStack(reflect.TypeOf(uint32(0)), sp))
    39          case reflect.Uint64        : return sp + 8, append(p, mkStack(reflect.TypeOf(uint64(0)), sp))
    40          case reflect.Uintptr       : return sp + 8, append(p, mkStack(reflect.TypeOf(uintptr(0)), sp))
    41          case reflect.Float32       : panic("abi: go116: not implemented: float32")
    42          case reflect.Float64       : panic("abi: go116: not implemented: float64")
    43          case reflect.Complex64     : panic("abi: go116: not implemented: complex64")
    44          case reflect.Complex128    : panic("abi: go116: not implemented: complex128")
    45          case reflect.Array         : panic("abi: go116: not implemented: arrays")
    46          case reflect.Chan          : return sp +  8, append(p, mkStack(reflect.TypeOf((chan int)(nil)), sp))
    47          case reflect.Func          : return sp +  8, append(p, mkStack(reflect.TypeOf((func())(nil)), sp))
    48          case reflect.Map           : return sp +  8, append(p, mkStack(reflect.TypeOf((map[int]int)(nil)), sp))
    49          case reflect.Ptr           : return sp +  8, append(p, mkStack(reflect.TypeOf((*int)(nil)), sp))
    50          case reflect.UnsafePointer : return sp +  8, append(p, mkStack(ptrType, sp))
    51          case reflect.Interface     : return sp + 16, append(p, mkStack(ptrType, sp), mkStack(ptrType, sp + 8))
    52          case reflect.Slice         : return sp + 24, append(p, mkStack(ptrType, sp), mkStack(intType, sp + 8), mkStack(intType, sp + 16))
    53          case reflect.String        : return sp + 16, append(p, mkStack(ptrType, sp), mkStack(intType, sp + 8))
    54          case reflect.Struct        : panic("abi: go116: not implemented: structs")
    55          default                    : panic("abi: invalid value type")
    56      }
    57  }
    58  
    59  func (self *AMD64ABI) Reserved() map[x86_64.Register64]int32 {
    60      return nil
    61  }
    62  
    63  func (self *AMD64ABI) LayoutFunc(id int, ft reflect.Type) *FunctionLayout {
    64      var sp uintptr
    65      var fn FunctionLayout
    66  
    67      /* allocate the receiver if any (interface call always uses pointer) */
    68      if id >= 0 {
    69          sp, fn.Args = salloc(fn.Args, sp, ptrType)
    70      }
    71  
    72      /* assign every arguments */
    73      for i := 0; i < ft.NumIn(); i++ {
    74          sp, fn.Args = salloc(fn.Args, sp, ft.In(i))
    75      }
    76  
    77      /* assign every return value */
    78      for i := 0; i < ft.NumOut(); i++ {
    79          sp, fn.Rets = salloc(fn.Rets, sp, ft.Out(i))
    80      }
    81  
    82      /* update function ID and stack pointer */
    83      fn.Id = id
    84      fn.Sp = sp
    85      return &fn
    86  }