How do you view tcl bytecode in tclsh (or otherwise)

I have seen the theory and understand the explanation why the former is faster than the latter, but I want to see bytecode in tcl. it's pretty easy to see the bytecode in python shell, but I'm having a hard time finding a solution to view this in tclsh.

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

      

Any help would be appreciated.

+3


source to share


1 answer


To see what Tcl bytecode generated, use tcl::unsupported::disassemble

(if you have Tcl 8.5 or newer). Here are your examples:

% 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 

      

As you can see, in one case Tcl found that it had a compile time constant and used that, and in another case it creates an expression and runs that into the runtime expression engine (through exprStk

which I can tell you, recursively calls the compiler on that which in this case is a completely new object and therefore won't cache anything and will be costly).

You can parse other things, especially proc

(for procedures), lambda

(for apply

terms) and method

(for TclOO methods, this requires Tcl 8.6).




In Tcl 8.4 and earlier, the disassembler can be parsed. You just set the global variable tcl_traceCompile

equal 2

- assuming the Tcl library was built with the correct configuration options, --enable-symbols=all

is the most useful option - and then force the code to compile; disassembly (same format) is printed directly to the real console. But it was a terrible way to do it; 8.5 added a version of the command to all assemblies to get away from this horrible bug with globals. (There's also tcl_traceExec

...)

8.6.3 will also have another disassembler that generates output suitable for subsequent scripts.

+2


source







All Articles