你如何检查tclsh(或其他)中的tcl字节码

时间:2014-10-02 16:31:33

标签: tcl bytecode

我已经看过这个理论并理解为什么第一个比第二个更快的解释,但我想在tcl中看到字节码。在python shell中,很容易看到字节码,但我找不到在tclsh中查看它的解决方案。

#first approach
expr {3 * 4}
#second approach
expr 3 * 4

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:2)

要查看Tcl生成的字节码,请使用tcl::unsupported::disassemble(假设您已获得Tcl 8.5或更高版本)。这是你的例子:

% tcl::unsupported::disassemble script {expr {3 * 4}}
ByteCode 0x0x103058910, refCt 1, epoch 95, interp 0x0x100829a10 (epoch 95)
  Source "expr {3 * 4}"
  Cmds 1, src 12, inst 3, litObjs 1, aux 0, stkDepth 1, code/src 0.00
  Commands 1:
      1: pc 0-1, src 0-11
  Command 1: "expr {3 * 4}"
    (0) push1 0     # "12"
    (2) done 

% tcl::unsupported::disassemble script {expr 3 * 4}
ByteCode 0x0x1030b2f10, refCt 1, epoch 95, interp 0x0x100829a10 (epoch 95)
  Source "expr 3 * 4"
  Cmds 1, src 10, inst 14, litObjs 4, aux 0, stkDepth 5, code/src 0.00
  Commands 1:
      1: pc 0-12, src 0-9
  Command 1: "expr 3 * 4"
    (0) push1 0     # "3"
    (2) push1 1     # " "
    (4) push1 2     # "*"
    (6) push1 1     # " "
    (8) push1 3     # "4"
    (10) concat1 5 
    (12) exprStk 
    (13) done 

正如您所看到的,在一种情况下,Tcl发现它有一个编译时常量并使用它,而在另一种情况下,它正在构建一个表达式并将其触发到运行时表达式引擎中(通过{{1}我可以告诉你递归地调用编译器,在这种情况下是什么 一个全新的对象,因此最终不会缓存任何东西而且会很昂贵。)

您可以反汇编其他内容,特别是exprStk(针对程序),proc(适用于lambda条款)和apply(适用于TclOO方法;此处需要Tcl 8.6)。


在Tcl 8.4及更早版本中,可以让反汇编程序打印出来。您只需将全局method变量设置为tcl_traceCompile - 如果使用正确的配置选项构建Tcl库,2是最有用的变量 - 然后强制编译代码;反汇编(相同的格式)直接打印到真正的控制台。但这是一种糟糕的方式; 8.5在所有版本中添加了命令版本,以便远离那些可怕的全局变量。 (还有--enable-symbols=all ...)

8.6.3也将有另一个反汇编程序,它产生适合进一步编写脚本的输出。