Bitarray Stepper
Pick a command, then step through what Tcl and bitarray.c do with it: which core function reaches
which hook, and how the bits and 64-bit words change. Change the width, the index or the value and the steps are recomputed.
Memory a simplified drawing of the real data; each 64-bit word is shown in hex
Code for this step
Call history newest at the top; 0 is always the library load
Tcl_ObjType hooks the slots the core can call
| Slot | bitarray |
|---|
Core map which core function reaches which hook (checked against the Tcl source, see below)
| Command | Core path | Hook |
|---|---|---|
llength $a | INST_LIST_LENGTH (tclExecute.c) → TclListObjLength (tclListObj.c) | lengthProc → BALength |
lindex $a i | INST_LIST_INDEX or INST_LIST_INDEX_IMM (tclExecute.c): TclObjTypeLength, then TclObjTypeIndex | indexProc → BAIndex |
lset a i v | INST_LSET_FLAT (tclExecute.c) → TclObjTypeSetElement; Tcl_LsetObjCmd → TclLsetList (tclListObj.c) takes the same route | setElementProc → BASetElement (it copies a shared array itself) |
lrange $a i j | INST_LIST_RANGE_IMM (tclExecute.c) or Tcl_LrangeObjCmd (tclCmdIL.c) → Tcl_ListObjRange (tclListTypes.c) → TclObjTypeSlice | sliceProc → BASlice |
lreverse $a | Tcl_LreverseObjCmd (tclCmdIL.c) → Tcl_ListObjReverse (tclListTypes.c) → TclObjTypeReverse | reverseProc → BAReverse |
lreplace $a i j … | INST_LREPLACE (tclExecute.c): Tcl_ListObjLength, Tcl_DuplicateObj if shared, then Tcl_ListObjReplace (tclListObj.c) → TclObjTypeReplace | replaceProc → BAReplace (copy through dupIntRepProc → BADup) |
foreach e $a | INST_FOREACH_STEP (tclExecute.c): Tcl_ListObjLength once, then Tcl_ListObjIndex per element | lengthProc, indexProc → BALength, BAIndex |
x in $a | INST_LIST_IN (tclExecute.c) → TclObjTypeInOperator | inOperProc → BAInOper |
join $a , | Tcl_JoinObjCmd (tclCmdIL.c) → TclObjTypeGetElements (the same for {*}$a and others that need every element) | getElementsProc → BAGetElements |
puts $a | Tcl_GetString → the type's updateStringProc | updateStringProc → BAUpdateString |
lappend a v | Tcl_ListObjAppendElement → TclListObjAppendElements → TclListObjGetRep → SetListFromAny (tclListObj.c) | no slot; SetListFromAny calls BALength, then BAIndex per element, and the array becomes a plain list |
bitarray and … | none: it is an ordinary command | BitarrayCmd → BitOpCmd → BitOpWords |
About this page
The steps were written from the sources: bitarray.c (Version 0.9.4) and the Tcl 9.1 source tree (GitHub mirror, commit
e36db33; files tclExecute.c, tclListObj.c, tclListTypes.c, tclCmdIL.c,
tclArithSeries.c). Function names are stable; line numbers and details can drift in later Tcl versions, so check the source
before relying on a name. The values drawn are computed by this page's own small model of the operations. They are not captured from
a running Tcl, and the page does not run Tcl or your build. The simplifications are: refcounts count only the variables shown (the real
value stack holds extra references for a moment); an array has 16 elements here (real ones are as long as you like); and
capWords is modelled only where a step grows the array (doubling, at least 4 words).
Timings and when to prefer a plain list are in performance_analysis.md; the full command syntax is in README.md.