Open ysweid opened 7 years ago
return, call and count hooks have been implemented.
Initial benchmark shows that if false condition
has no effect at all.
Close issue?
any progress? need this pr
Indeed it would be very nice to see the getting merged and I think this would be a very useful feature. Currently its a bit hard to debug scripts running on gopher-lua.
@ysweid Since I need to analyse glua performance issues, I tried to use your hook implementation and had some problems: 1.bug found:in
https://github.com/ysweid/gopher-lua/blob/39e4eebec3f18f3d5de4d9ccc1410f4e5d37f90f/hook.go#L24
.You need to add a variable or recursively search for parent to avoid this: when a line hook 's callback function contains a function call, it appears that the callback function itself triggers the line hook,code like this:(add isCalled variable)
if currentline != 0 && cf.Fn != lh.callback && currentline != L.prevline{
lh.isCalled = true
L.reg.Push(lh.callback)
L.reg.Push(LString("line"))
L.reg.Push(LNumber(currentline))
L.callR(2, 0, -1)
L.prevline = currentline
lh.isCalled = false
}
or recursively search for parent and add a judgemental condition: !isFunctionInCallFrameChain(cf, rh.callback):
func isFunctionInCallFrameChain(cf *callFrame, fn *LFunction) bool {
if cf.Fn == fn {
return true
}
if cf.Parent != nil {
return isFunctionInCallFrameChain(cf.Parent, fn)
}
return false
}
2. two questions 2.1 I tried to use luatrace tool in gopher-lua,several places appear to behave differently from lua using the c language: when line and call hook are both used,c-lua first trigger call hook and then line hook,but glua is the opposite. I tried to change this but failed: my change like this:
return_value:=jumpTable[int(inst>>26)](L, inst, baseframe)
if L.lhook != nil {
L.lhook.call(L, cf)
}
if L.cthook != nil {
L.cthook.call(L, cf)
}
if return_value == 1 {
return
}
The reason I changed it is that I noticed that the jumpTable is only used here, and the call hook is added to the call function in the jumpTable,but it doesn't work.I'm curious as to why it didn't work. 2.2 Finally,I found in tailcall condition(such as this: return func()): gopher-lua looks to optimise all the tailcalls into one function with only once return hook trigger,but in c-lua it will trigger return hook whether or not is tailcall,I don't know where to change this,maybe in jumpTable? (because I noticed that there's only OP_TAILCALL function in jumpTable, do not have OP_TAILRETURN)?
This issue is created to introduce hooks in gopher-lua.
Implementation:
Hooker
interface will be created, that hascall
andString
functions.lhook
,rhook
,chook
andcthook
areHooker
typed variables that will be declared inLState
struct. andprevline
to keep track of last executed line.call
function will be used to execute the behaviour of the hook.LineHook
call implementation.<= 0
to keepcount
hook disabled.Progress: I have already implemented the four hooks. Line hook required me to fix a bug (I guess) in
compile.go
that was ignoring the table items lines when the table expression gets compiled.Test case: hook.lua
Glua's output:
Lua output:
Outputs differences:
It is interesting that Lua looped over the
obj
table from the last item to the first, while Glua started from the first item. (Not sure whether it's matter ofpairs
implementation orfor in
loop).Lua jumps over
end
label ofwhile
statement, while Glua counts it.As for
call
,return
hooks, I can tell thatlua
is making way more calls to the callback thanglua
. It's either I need to call the hooks in places I'm not aware of, or we're making less calls toOP_RETURN
andOP_CALL
.Missing:
Compiled and tested on:
@yuin I pushed a PR for early review, and to let you confirm the implementation.