loader_latest.go raw

   1  
   2  /*
   3   * Copyright 2021 ByteDance Inc.
   4   *
   5   * Licensed under the Apache License, Version 2.0 (the "License");
   6   * you may not use this file except in compliance with the License.
   7   * You may obtain a copy of the License at
   8   *
   9   *     http://www.apache.org/licenses/LICENSE-2.0
  10   *
  11   * Unless required by applicable law or agreed to in writing, software
  12   * distributed under the License is distributed on an "AS IS" BASIS,
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14   * See the License for the specific language governing permissions and
  15   * limitations under the License.
  16   */
  17  
  18  package loader
  19  
  20  import (
  21      `github.com/bytedance/sonic/loader/internal/rt`
  22  )
  23  
  24  // LoadFuncs loads only one function as module, and returns the function pointer
  25  //   - text: machine code
  26  //   - funcName: function name
  27  //   - frameSize: stack frame size. 
  28  //   - argSize: argument total size (in bytes)
  29  //   - argPtrs: indicates if a slot (8 Bytes) of arguments memory stores pointer, from low to high
  30  //   - localPtrs: indicates if a slot (8 Bytes) of local variants memory stores pointer, from low to high
  31  // 
  32  // WARN: 
  33  //   - the function MUST has fixed SP offset equaling to this, otherwise it go.gentraceback will fail
  34  //   - the function MUST has only one stack map for all arguments and local variants
  35  func (self Loader) LoadOne(text []byte, funcName string, frameSize int, argSize int, argPtrs []bool, localPtrs []bool) Function {
  36      size := uint32(len(text))
  37  
  38      fn := Func{
  39          Name: funcName,
  40          TextSize: size,
  41          ArgsSize: int32(argSize),
  42      }
  43  
  44      // NOTICE: suppose the function has fixed SP offset equaling to frameSize, thus make only one pcsp pair
  45      fn.Pcsp = &Pcdata{
  46          {PC: size, Val: int32(frameSize)},
  47      }
  48  
  49      if self.NoPreempt {
  50          fn.PcUnsafePoint = &Pcdata{
  51              {PC: size, Val: PCDATA_UnsafePointUnsafe},
  52          }
  53      } else {
  54          fn.PcUnsafePoint = &Pcdata{
  55              {PC: size, Val: PCDATA_UnsafePointSafe},
  56          }
  57      }
  58  
  59      // NOTICE: suppose the function has only one stack map at index 0
  60      fn.PcStackMapIndex = &Pcdata{
  61          {PC: size, Val: 0},
  62      }
  63  
  64      if argPtrs != nil {
  65          args := rt.StackMapBuilder{}
  66          for _, b := range argPtrs {
  67              args.AddField(b)
  68          }
  69          fn.ArgsPointerMaps = args.Build()
  70      }
  71      
  72      if localPtrs != nil {
  73          locals := rt.StackMapBuilder{}
  74          for _, b := range localPtrs {
  75              locals.AddField(b)
  76          }
  77          fn.LocalsPointerMaps = locals.Build()
  78      }
  79  
  80      out := Load(text, []Func{fn}, self.Name + funcName, []string{self.File})
  81      return out[0]
  82  }
  83  
  84  // Load loads given machine codes and corresponding function information into go moduledata
  85  // and returns runnable function pointer
  86  // WARN: this API is experimental, use it carefully
  87  func Load(text []byte, funcs []Func, modulename string, filenames []string) (out []Function) {
  88      ids := make([]string, len(funcs))
  89      for i, f := range funcs {
  90          ids[i] = f.Name
  91      }
  92      // generate module data and allocate memory address
  93      mod := makeModuledata(modulename, filenames, &funcs, text)
  94  
  95      // verify and register the new module
  96      moduledataverify1(mod)
  97      registerModule(mod)
  98  
  99      // 
 100      // encapsulate function address
 101      out = make([]Function, len(funcs))
 102      for i, s := range ids {
 103          for _, f := range funcs {
 104              if f.Name == s {
 105                  m := uintptr(mod.text + uintptr(f.EntryOff))
 106                  out[i] = Function(&m)
 107              }
 108          }
 109      }
 110      return 
 111  }
 112