...

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

Documentation: github.com/bytedance/sonic/loader

     1  //go:build go1.17
     2  // +build go1.17
     3  
     4  /*
     5   * Copyright 2021 ByteDance Inc.
     6   *
     7   * Licensed under the Apache License, Version 2.0 (the "License");
     8   * you may not use this file except in compliance with the License.
     9   * You may obtain a copy of the License at
    10   *
    11   *     http://www.apache.org/licenses/LICENSE-2.0
    12   *
    13   * Unless required by applicable law or agreed to in writing, software
    14   * distributed under the License is distributed on an "AS IS" BASIS,
    15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16   * See the License for the specific language governing permissions and
    17   * limitations under the License.
    18   */
    19  
    20  package loader
    21  
    22  import (
    23      `runtime`
    24      `runtime/debug`
    25      `strconv`
    26      `testing`
    27      `unsafe`
    28  
    29      `github.com/bytedance/sonic/internal/rt`
    30      `github.com/stretchr/testify/require`
    31  )
    32  
    33  func TestLoad(t *testing.T) {
    34      // defer func() {
    35      //     if r := recover(); r != nil {
    36      //         runtime.GC()
    37      //         if r != "hook1" {
    38      //             t.Fatal("not right panic:" + r.(string))
    39      //         }
    40      //     } else {
    41      //         t.Fatal("not panic")
    42      //     }
    43      // }()
    44  
    45      var hstr string
    46  
    47      type TestFunc func(i *int, hook func(i *int)) int
    48      var hook = func(i *int) {
    49          runtime.GC()
    50          debug.FreeOSMemory()
    51          hstr = ("hook" + strconv.Itoa(*i))
    52          runtime.GC()
    53          debug.FreeOSMemory()
    54      }
    55      // var f TestFunc = func(i *int, hook func(i *int)) int {
    56      //     var t = *i
    57      //     hook(i)
    58      //     return t + *i
    59      // }
    60      bc := []byte {
    61          0x48, 0x83, 0xec, 0x18,         // (0x00) subq $24, %rsp
    62          0x48, 0x89, 0x6c, 0x24, 0x10,   // (0x04) movq %rbp, 16(%rsp)
    63          0x48, 0x8d, 0x6c, 0x24, 0x10,   // (0x09) leaq 16(%rsp), %rbp
    64          0x48, 0x89, 0x44, 0x24, 0x20,   // (0x0e) movq %rax, 32(%rsp)
    65          0x48, 0x8b, 0x08,               // (0x13) movq (%rax), %rcx
    66          0x48, 0x89, 0x4c, 0x24, 0x08,   // (0x16) movq %rcx, 8(%rsp)
    67          0x48, 0x8b, 0x33,               // (0x1b) movq (%rbx), %rsi
    68          0x48, 0x89, 0xda,               // (0x1e) movq %rbx, %rdx
    69          0xff, 0xd6,                     // (0x21) callq %rsi
    70          0x48, 0x8b, 0x44, 0x24, 0x08,   // (0x23) movq 8(%rsp), %rax
    71          0x48, 0x8b, 0x4c, 0x24, 0x20,   // (0x28) movq 32(%rsp), %rcx
    72          0x48, 0x03, 0x01,               // (0x2d) addq (%rcx), %rax
    73          0x48, 0x8b, 0x6c, 0x24, 0x10,   // (0x30) movq 16(%rsp), %rbp
    74          0x48, 0x83, 0xc4, 0x18,         // (0x35) addq $24, %rsp
    75          0xc3,                           // (0x39) ret
    76      }
    77      size := uint32(len(bc))
    78      fn := Func{
    79          ID: 0,
    80          Flag: 0,
    81          ArgsSize: 16,
    82          EntryOff: 0,
    83          TextSize: size,
    84          DeferReturn: 0,
    85          FileIndex: 0,
    86          Name: "dummy",
    87      }
    88  
    89      fn.Pcsp = &Pcdata{
    90          {PC: size, Val: 24},
    91      }
    92  
    93      fn.Pcline = &Pcdata{
    94          {PC: 0x01, Val: 0},
    95          {PC: 0x0e, Val: 1},
    96          {PC: 0x1d, Val: 2},
    97          {PC: size, Val: 3},
    98      }
    99  
   100      fn.Pcfile = &Pcdata{
   101          {PC: size, Val: 0},
   102      }
   103  
   104      fn.PcUnsafePoint = &Pcdata{
   105          {PC: size, Val: PCDATA_UnsafePointUnsafe},
   106      }
   107  
   108      fn.PcStackMapIndex = &Pcdata{
   109          {PC: size, Val: 0},
   110      }
   111  
   112      args := rt.StackMapBuilder{}
   113      args.AddField(true)
   114      args.AddField(true)
   115      fn.ArgsPointerMaps = args.Build()
   116  
   117      locals := rt.StackMapBuilder{}
   118      locals.AddField(false)
   119      locals.AddField(false)
   120      fn.LocalsPointerMaps = locals.Build()
   121  
   122      rets := Load(bc, []Func{fn}, "dummy_module", []string{"github.com/bytedance/sonic/dummy.go"})
   123      println("func address ", *(*unsafe.Pointer)(rets[0]))
   124      // for k, _ := range moduleCache.m {
   125      //     spew.Dump(k)
   126      // }
   127  
   128      f := *(*TestFunc)(unsafe.Pointer(&rets[0]))
   129      i := 1
   130      j := f(&i, hook)
   131      require.Equal(t, 2, j)
   132      require.Equal(t, "hook1", hstr)
   133  
   134      fi := runtime.FuncForPC(*(*uintptr)(rets[0]))
   135      require.Equal(t, "dummy", fi.Name())
   136      file, line := fi.FileLine(0)
   137      require.Equal(t, "github.com/bytedance/sonic/dummy.go", file)
   138      require.Equal(t, 0, line)
   139  }
   140  

View as plain text