...

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

Documentation: github.com/bytedance/sonic/loader

     1  //go:build go1.16 && !go1.17
     2  // +build go1.16,!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      `fmt`
    24      `runtime`
    25      `runtime/debug`
    26      `strconv`
    27      `testing`
    28      `unsafe`
    29  
    30      `github.com/bytedance/sonic/internal/rt`
    31      `github.com/stretchr/testify/require`
    32  )
    33  
    34  func TestLoad(t *testing.T) {
    35      // defer func() {
    36      //     if r := recover(); r != nil {
    37      //         runtime.GC()
    38      //         if r != "hook1" {
    39      //             t.Fatal("not right panic:" + r.(string))
    40      //         }
    41      //     } else {
    42      //         t.Fatal("not panic")
    43      //     }
    44      // }()
    45  
    46      var hstr string
    47  
    48      type TestFunc func(i *int, hook func(i *int)) int
    49      var hook = func(i *int) {
    50          runtime.GC()
    51          debug.FreeOSMemory()
    52          hstr = ("hook" + strconv.Itoa(*i))
    53          runtime.GC()
    54          debug.FreeOSMemory()
    55      }
    56      // var f TestFunc = func(i *int, hook func(i *int)) int {
    57      //     var t = *i
    58      //     hook(i)
    59      //     return t + *i
    60      // }
    61      bc := []byte {
    62          0x48, 0x83, 0xec, 0x18,       // (0x00) subq $24, %rsp
    63          0x48, 0x89, 0x6c, 0x24, 0x10, // (0x04) movq %rbp, 16(%rsp)
    64          0x48, 0x8d, 0x6c, 0x24, 0x10, // (0x09) leaq 16(%rsp), %rbp
    65          0x48, 0x8b, 0x44, 0x24, 0x20, // (0x0e) movq 32(%rsp), %rax
    66          0x48, 0x8b, 0x08,             // (0x13) movq (%rax), %rcx
    67          0x48, 0x89, 0x4c, 0x24, 0x08, // (0x16) movq %rcx, 8(%rsp)
    68          0x48, 0x8b, 0x54, 0x24, 0x28, // (0x1b) movq 40(%rsp), %rdx
    69          0x48, 0x8b, 0x1a,             // (0x20) movq (%rdx), %rbx
    70          0x48, 0x89, 0x04, 0x24,       // (0x23) movq %rax, (%rsp)
    71          0xff, 0xd3,                   // (0x27) callq %rbx
    72          0x48, 0x8b, 0x44, 0x24, 0x08, // (0x29) movq 8(%rsp), %rax
    73          0x48, 0x8b, 0x4c, 0x24, 0x20, // (0x2e) movq 32(%rsp), %rcx
    74          0x48, 0x03, 0x01,             // (0x33) addq (%rcx), %rax
    75          0x48, 0x89, 0x44, 0x24, 0x30, // (0x36) movq %rax, 48(%rsp)
    76          0x48, 0x8b, 0x6c, 0x24, 0x10, // (0x3b) movq 16(%rsp), %rbp
    77          0x48, 0x83, 0xc4, 0x18,       // (0x40) addq $24, %rsp
    78          0xc3,                         // (0x44) ret
    79      }
    80      
    81      size := uint32(len(bc))
    82      fn := Func{
    83          ID: 0,
    84          Flag: 0,
    85          ArgsSize: 16,
    86          EntryOff: 0,
    87          TextSize: size,
    88          DeferReturn: 0,
    89          FileIndex: 0,
    90          Name: "dummy",
    91      }
    92  
    93      fn.Pcsp = &Pcdata{
    94          {PC: size, Val: 24},
    95      }
    96  
    97      fn.Pcline = &Pcdata{
    98          {PC: 0x13, Val: 0},
    99          {PC: 0x1b, Val: 1},
   100          {PC: 0x23, Val: 2},
   101          {PC: size, Val: 3},
   102      }
   103  
   104      fn.Pcfile = &Pcdata{
   105          {PC: size, Val: 0},
   106      }
   107  
   108      fn.PcUnsafePoint = &Pcdata{
   109          {PC: size, Val: PCDATA_UnsafePointUnsafe},
   110      }
   111  
   112      fn.PcStackMapIndex = &Pcdata{
   113          {PC: size, Val: 0},
   114      }
   115  
   116      args := rt.StackMapBuilder{}
   117      args.AddField(true)
   118      args.AddField(true)
   119      fn.ArgsPointerMaps = args.Build()
   120      ab, _ :=  fn.ArgsPointerMaps.MarshalBinary()
   121      fmt.Printf("args: %+v\n", ab)
   122  
   123      locals := rt.StackMapBuilder{}
   124      locals.AddField(false)
   125      locals.AddField(false)
   126      fn.LocalsPointerMaps = locals.Build()
   127      lb, _ :=  fn.LocalsPointerMaps.MarshalBinary()
   128      fmt.Printf("locals: %+v\n", lb)
   129  
   130      rets := Load(bc, []Func{fn}, "dummy_module", []string{"github.com/bytedance/sonic/dummy.go"})
   131      println("func address ", *(*unsafe.Pointer)(rets[0]))
   132      // for k, _ := range moduleCache.m {
   133      //     spew.Dump(k)
   134      // }
   135      f := *(*TestFunc)(unsafe.Pointer(&rets[0]))
   136      i := 1
   137      j := f(&i, hook)
   138      require.Equal(t, 2, j)
   139      require.Equal(t, "hook1", hstr)
   140  
   141      fi := runtime.FuncForPC(*(*uintptr)(rets[0]))
   142      require.Equal(t, "dummy", fi.Name())
   143      file, line := fi.FileLine(0)
   144      require.Equal(t, "github.com/bytedance/sonic/dummy.go", file)
   145      require.Equal(t, 0, line)
   146  }
   147  

View as plain text