...

Source file src/github.com/bytedance/sonic/loader/loader_latest.go

Documentation: github.com/bytedance/sonic/loader

     1  // +build go1.16,!go1.23
     2  
     3  /*
     4   * Copyright 2021 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 loader
    20  
    21  import (
    22      `github.com/bytedance/sonic/internal/rt`
    23  )
    24  
    25  // LoadFuncs loads only one function as module, and returns the function pointer
    26  //   - text: machine code
    27  //   - funcName: function name
    28  //   - frameSize: stack frame size. 
    29  //   - argSize: argument total size (in bytes)
    30  //   - argPtrs: indicates if a slot (8 Bytes) of arguments memory stores pointer, from low to high
    31  //   - localPtrs: indicates if a slot (8 Bytes) of local variants memory stores pointer, from low to high
    32  // 
    33  // WARN: 
    34  //   - the function MUST has fixed SP offset equaling to this, otherwise it go.gentraceback will fail
    35  //   - the function MUST has only one stack map for all arguments and local variants
    36  func (self Loader) LoadOne(text []byte, funcName string, frameSize int, argSize int, argPtrs []bool, localPtrs []bool) Function {
    37      size := uint32(len(text))
    38  
    39      fn := Func{
    40          Name: funcName,
    41          TextSize: size,
    42          ArgsSize: int32(argSize),
    43      }
    44  
    45      // NOTICE: suppose the function has fixed SP offset equaling to frameSize, thus make only one pcsp pair
    46      fn.Pcsp = &Pcdata{
    47          {PC: size, Val: int32(frameSize)},
    48      }
    49  
    50      if self.NoPreempt {
    51          fn.PcUnsafePoint = &Pcdata{
    52              {PC: size, Val: PCDATA_UnsafePointUnsafe},
    53          }
    54      } else {
    55          fn.PcUnsafePoint = &Pcdata{
    56              {PC: size, Val: PCDATA_UnsafePointSafe},
    57          }
    58      }
    59  
    60      // NOTICE: suppose the function has only one stack map at index 0
    61      fn.PcStackMapIndex = &Pcdata{
    62          {PC: size, Val: 0},
    63      }
    64  
    65      if argPtrs != nil {
    66          args := rt.StackMapBuilder{}
    67          for _, b := range argPtrs {
    68              args.AddField(b)
    69          }
    70          fn.ArgsPointerMaps = args.Build()
    71      }
    72      
    73      if localPtrs != nil {
    74          locals := rt .StackMapBuilder{}
    75          for _, b := range localPtrs {
    76              locals.AddField(b)
    77          }
    78          fn.LocalsPointerMaps = locals.Build()
    79      }
    80  
    81      out := Load(text, []Func{fn}, self.Name + funcName, []string{self.File})
    82      return out[0]
    83  }
    84  
    85  // Load loads given machine codes and corresponding function information into go moduledata
    86  // and returns runnable function pointer
    87  // WARN: this API is experimental, use it carefully
    88  func Load(text []byte, funcs []Func, modulename string, filenames []string) (out []Function) {
    89      ids := make([]string, len(funcs))
    90      for i, f := range funcs {
    91          ids[i] = f.Name
    92      }
    93      // generate module data and allocate memory address
    94      mod := makeModuledata(modulename, filenames, &funcs, text)
    95  
    96      // verify and register the new module
    97      moduledataverify1(mod)
    98      registerModule(mod)
    99  
   100      // 
   101      // encapsulate function address
   102      out = make([]Function, len(funcs))
   103      for i, s := range ids {
   104          for _, f := range funcs {
   105              if f.Name == s {
   106                  m := uintptr(mod.text + uintptr(f.EntryOff))
   107                  out[i] = Function(&m)
   108              }
   109          }
   110      }
   111      return 
   112  }
   113  

View as plain text