Tcl Source Code

Ticket Change Details
Login
Overview

Artifact ID: 9d09f61c99c7a196948e55b7a3c9b9c86887e0c9fb18a0bf8e53f45c4fafca90
Ticket: 552ed5eac53ff5e4685badea56935871627aff34
Strange discrepancy regarding INST_START_CMD in body of cycles if compiled with or without invocation in condition/iterator...
User & Date: sebres 2018-04-20 20:33:30
Changes

  1. assignee changed to: "nobody"
  2. closer changed to: "nobody"
  3. cmimetype changed to: "text/x-fossil-wiki"
  4. comment changed to:
    During working on my performance branch (BTW interim state: 8.6th is ca. 6-7 times faster now, but I'm confident it'll outperform 10x plank soon), I found strange discrepancy between two almost equal code-pieces.
    
    If one take a look into the byte-code of following scripts, he notes each set-command in first body receives additionally a 9-byte instruction "startCommand" (INST_START_CMD). This is good so (is also very fast command), but the second body totally misses it.
    
    Just compare both disassemble-outputs of:
    <code><verbatim>
    proc x {} {while {[t]} {set i0 0; set i1 1; set i2 2; set i3 3}}; tcl::unsupported::disassemble proc x
    proc x {} {while {$va} {set i0 0; set i1 1; set i2 2; set i3 3}}; tcl::unsupported::disassemble proc x
    </verbatim></code>
    Therefore it results in:
    
    <code><verbatim>
    Source "while {[t]} {set i0 0; set i1 1; set i2 2; set i3 3}"
    Cmds 6, src 52, inst 68, litObjs 6, aux 0, stkDepth 1, code/src 0.00
    ...
    Source "while {$va} {set i0 0; set i1 1; set i2 2; set i3 3}"
    Cmds 5, src 52, inst 30, litObjs 5, aux 0, stkDepth 1, code/src 0.00
    ...
    </verbatim></code>
    
    The same is valid for all cycles (resp. body compilations so different if it does or does not contain invocation), e. g. on following "foreach":
    
    <code><verbatim>
    proc x {} {set i1 0; unset i1; foreach a [test_itr] {set i0 0; set i1 1; set i2 2; set i3 3}}; tcl::unsupported::disassemble proc x
    proc x {} {set i1 0; unset i1; foreach a {a1 a2 a3} {set i0 0; set i1 1; set i2 2; set i3 3}}; tcl::unsupported::disassemble proc x
    </verbatim></code>
    
    results in:
    
    <code><verbatim>
    Source "set i1 0; unset i1; foreach a [test_itr] {set i0 0; set..."
    Cmds 8, src 81, inst 102, litObjs 6, aux 1, stkDepth 4, code/src 0.00
    ...
    Source "set i1 0; unset i1; foreach a {a1 a2 a3} {set i0 0; set..."
    Cmds 7, src 81, inst 46, litObjs 6, aux 1, stkDepth 4, code/src 0.00
    ...
    </verbatim></code>
    
    And each 68 vs 30 resp. 74 vs 36 bytes of code.
    This is wrong (and weird at all).
    
    BTW. Strange is also, in 8.5 as well as in my (own) another TclSE-edition, I can't see the same behavior (but some time ago I've rewritten there the handling round about "startCommand", so for example I don't have there `envPtr->atCmdStart` at all, it was implemented other way).
    
    I'm relative sure, this 4 extra "startCommand" commands in body are missed in both second variants (I'm sure this will wrong calculate the count of interpreted command).
    So for example "info cmdcount" as well as interpreter limit will work totally wrong.
    
    Following example illustrates the issue:
    
    <code><verbatim>
    proc retv {v} {return $v}
    set i 0
    foreach c {
        { set j 10; while {[retv [incr j -1]]} {set i0 0; set i1 1; set i2 2; set i3 3} }
        { set j 10; while {      [incr j -1] } {set i0 0; set i1 1; set i2 2; set i3 3} }
        { foreach j [retv {9 8 7 6 4 3 2 1}]   {set i0 0; set i1 1; set i2 2; set i3 3} }
        { foreach j       {9 8 7 6 4 3 2 1}    {set i0 0; set i1 1; set i2 2; set i3 3} }
    } {
        proc test_[incr i] {} $c
    }
    proc test {} {
        foreach i {1 2 3 4} {
            puts "[set cc [info cmdcount]]"
            test_$i
            puts "++ [expr {[info cmdcount] - $cc}]"
        }
    }
    test
    </verbatim></code>
    
    Result should be:
    <code><verbatim>
    ++ 62
    ++ 52
    ++ 38
    ++ 37
    </verbatim></code>
    And in current 8.6th it results in:
    <code><verbatim>
    ++ 62
    ++ 5     *WRONG*
    ++ 38
    ++ 5     *WRONG*
    </verbatim></code>
    
  5. foundin changed to: "8.6"
  6. is_private changed to: "0"
  7. login: "sebres"
  8. priority changed to: "5 Medium"
  9. resolution changed to: "None"
  10. severity changed to: "Important"
  11. status changed to: "Open"
  12. submitter changed to: "sebres"
  13. subsystem changed to: "47. Bytecode Compiler"
  14. title changed to:
    Strange discrepancy regarding INST_START_CMD in body of cycles if compiled with or without invocation in condition/iterator...
    
  15. type changed to: "Bug"