Menu

#595 Create compiled ensembles

open
3
2012-05-26
2010-10-29
gustafn
No

The following problem showed up in aolserver, which produces a blueprint of all tcl-commands for initializing per-thread interpreter. This blueprint contains app procs, .... and as well ensembles. When a Tcl ensemble (e.g. info) is recreated, it looses its compileProc, which has the consequence that e.g. "info exists" is not compiled properly anymore. Not sure, if this qualifies as a bug, but it is certainly "unexpected behavior".

The problem at hand can be "solved" by reconfiguring instead of redefining preexisting ensembles (my current fix), but i would think that using TclCompileEnsemble() would make as well sense for user ensembles, which could benefit as well from the compiler, when the ensemble contains e.g. "info exists". I would have expected, that all ensembles have the same compileProc.

The details: the script below shows the bytecode before and after a scripted ensemble definition. before, "info exists" is compiled to

Command 1: "info exists foo"
(0) existScalar %v0 # var "foo"
(5) done

after, it is just the "info command"

Command 1: "info exists foo"
(0) push1 0 # "info"
(2) push1 1 # "exists"
(4) push1 2 # "foo"
(6) invokeStk1 3
(8) done

This was observed with tcl 8.5.9 and tcl 8.6b*, mac os x and debian/ubuntu linux (32 and 64bit)
-gustaf neumann

======================================
proc foo {} {info exists foo}
puts [::tcl::unsupported::disassemble proc foo]

namespace eval ::tcl::info {
namespace ensemble create -command ::info -unknown {} -subcommands {} -prefixes 1 -map {
args ::tcl::info::args body ::tcl::info::body cmdcount ::tcl::info::cmdcount
commands ::tcl::info::commands complete ::tcl::info::complete default ::tcl::info::default
exists ::tcl::info::exists frame ::tcl::info::frame functions ::tcl::info::functions
globals ::tcl::info::globals hostname ::tcl::info::hostname level ::tcl::info::level
library ::tcl::info::library loaded ::tcl::info::loaded locals ::tcl::info::locals
nameofexecutable ::tcl::info::nameofexecutable patchlevel ::tcl::info::patchlevel
procs ::tcl::info::procs script ::tcl::info::script
sharedlibextension ::tcl::info::sharedlibextension tclversion ::tcl::info::tclversion
vars ::tcl::info::vars}
}
proc foo {} {info exists foo}
puts [::tcl::unsupported::disassemble proc foo]

Discussion

  • Donal K. Fellows

    I know it's awkward, but the problem is that being compilable adds a fairly heavy overhead to the ensemble; every time the ensemble is modified, it causes a flush of all existing bytecodes and a rebuild from source of everything (well, it bumps an epoch counter which has that effect). I didn't want to inflict that cost on everything so non-compiled ensembles are much cheaper to modify (so packages like Snit weren't massively punished) but that has the side effect of meaning that these complexity costs are necessarily borne *somewhere*.

     
  • Donal K. Fellows

    Maybe it would be easier to do something smarter... but I don't know what to do right now. This was the best compromise I could think of. :-)

     
  • miguel sofer

    miguel sofer - 2011-01-31
    • assigned_to: msofer --> dkf
     
  • Donal K. Fellows

    • labels: 105662 --> 21. [namespace]
    • summary: ensemble loosing compileProc --> Create compiled ensembles
     
  • Donal K. Fellows

    A workaround is to simply update the existing ::info ensemble with a new -map

     
  • Donal K. Fellows

    • priority: 5 --> 3