github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/loader/loader_go117_test.go (about) 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/goshafaq/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/goshafaq/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/goshafaq/sonic/dummy.go", file) 138 require.Equal(t, 0, line) 139 }