1
2
3
4
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
36
37
38
39
40
41
42
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
57
58
59
60
61 bc := []byte {
62 0x48, 0x83, 0xec, 0x18,
63 0x48, 0x89, 0x6c, 0x24, 0x10,
64 0x48, 0x8d, 0x6c, 0x24, 0x10,
65 0x48, 0x8b, 0x44, 0x24, 0x20,
66 0x48, 0x8b, 0x08,
67 0x48, 0x89, 0x4c, 0x24, 0x08,
68 0x48, 0x8b, 0x54, 0x24, 0x28,
69 0x48, 0x8b, 0x1a,
70 0x48, 0x89, 0x04, 0x24,
71 0xff, 0xd3,
72 0x48, 0x8b, 0x44, 0x24, 0x08,
73 0x48, 0x8b, 0x4c, 0x24, 0x20,
74 0x48, 0x03, 0x01,
75 0x48, 0x89, 0x44, 0x24, 0x30,
76 0x48, 0x8b, 0x6c, 0x24, 0x10,
77 0x48, 0x83, 0xc4, 0x18,
78 0xc3,
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
133
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