有什么方法可以从指定的 proc 名称计算执行前的命令(可能是调用栈编号,包括 tclcmds)?我认为需要假设源是可用的(不是预编译的)。 谢谢。
最佳答案
动态分析
您可以使用跟踪来查找在执行特定过程期间执行了多少命令。假设命令没有重新输入(即,不是递归的),您可以:
proc theProcedureOfInterest {} {
# Whatever in here...
for {set i 0} {$i < 5} {incr i} {
puts i=$i
}
}
trace add execution theProcedureOfInterest {enter leave enterstep} countCalls
proc countCalls {cmd args} {
global counter
switch [lindex $args end] {
enter {
set counter 0
}
enterstep {
incr counter
puts >>>$cmd
}
leave {
puts "$counter calls in $cmd"
}
}
}
theProcedureOfInterest
如果你执行上面的代码,你会得到这个输出:
>>>for {set i 0} {$i < 5} {incr i} { puts i=$i } >>>set i 0 >>>puts i=0 i=0 >>>incr i >>>puts i=1 i=1 >>>incr i >>>puts i=2 i=2 >>>incr i >>>puts i=3 i=3 >>>incr i >>>puts i=4 i=4 >>>incr i 12 calls in theProcedureOfInterest
That code has 12 command calls inside it, and you can count them yourself too.
This will also trace into procedures called from that procedure (and making it handle recursive calls is possible, but rather more involved). Be aware that changing the definition of the procedure will remove the trace (just reapply it if desired) and also note that this sort of tracing has a substantial performance impact (it greatly inhibits possible optimizations in Tcl's bytecode compiler).
Static Analysis
To get a static analysis of the code, you need the dkf-improved-disassembler
branch (I've not merged it yet). Then, you can do:
set disassembled [::tcl::unsupported::getbytecode script {
# Whatever in here...
for {set i 0} {$i < 5} {incr i} {
puts i=$i
}
}]
set commandCount [llength [dict get $disassembled commands]]
您还可以查看 commands
元素以查看已识别的命令 (dict get [lindex [dict get $disassembled commands] $n] source
)。它会检查像 for
这样的命令,但不会检查带有主体的自定义命令(因为它不明白它们是代码的一部分,而不仅仅是一个有趣的字符串)。它也不知道它们被执行的频率;毕竟是静态分析。
关于windows - 在 tcl 中计算 proc 内的命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23107433/