forked from yuin/gopher-lua
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhook.go
106 lines (88 loc) · 1.85 KB
/
hook.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package lua
import "fmt"
type Hooker interface {
call(L *LState, cf *callFrame)
String() string
}
type LHook struct {
callback *LFunction
line int
}
func newLHook(callback *LFunction, line int) *LHook {
return &LHook{
callback: callback,
line: line,
}
}
func (lh *LHook) call(L *LState, cf *callFrame) {
currentline := cf.Fn.Proto.DbgSourcePositions[cf.Pc-1]
if currentline != 0 && cf.Fn != lh.callback && currentline != L.prevline {
L.reg.Push(lh.callback)
L.reg.Push(LString("line"))
L.reg.Push(LNumber(currentline))
L.callR(2, 0, -1)
L.prevline = currentline
}
}
func (lh *LHook) String() string {
return fmt.Sprintf("hook: %p", lh)
}
type CTHook struct {
callback *LFunction
count int
currentCount int
}
func newCTHook(callback *LFunction, count int) *CTHook {
return &CTHook{
callback: callback,
count: count,
}
}
func (ct *CTHook) call(L *LState, cf *callFrame) {
ct.currentCount++
if ct.currentCount == ct.count {
L.reg.Push(ct.callback)
L.reg.Push(LString("count"))
L.callR(1, 0, -1)
ct.currentCount = 0
}
}
func (ct *CTHook) String() string {
return fmt.Sprintf("hook: %p", ct)
}
type CHook struct {
callback *LFunction
}
func newCHook(callback *LFunction) *CHook {
return &CHook{
callback: callback,
}
}
func (ch *CHook) call(L *LState, cf *callFrame) {
if ch.callback != cf.Fn {
L.reg.Push(ch.callback)
L.reg.Push(LString("call"))
L.callR(1, 0, -1)
}
}
func (ch *CHook) String() string {
return fmt.Sprintf("hook: %p", ch)
}
type RHook struct {
callback *LFunction
}
func newRHook(callback *LFunction) *RHook {
return &RHook{
callback: callback,
}
}
func (rh *RHook) call(L *LState, cf *callFrame) {
if rh.callback != cf.Fn {
L.reg.Push(rh.callback)
L.reg.Push(LString("return"))
L.callR(1, 0, -1)
}
}
func (rh *RHook) String() string {
return fmt.Sprintf("hook: %p", rh)
}