Posted to tcl by aspect at Mon Jun 22 05:52:10 GMT 2015view pretty

cannot get {TCL OPERATION LREPLACE BADID} from an empty list

There appears to be special bytecode in compiled lreplace so that an empty list
will not trigger the above error (see * in disassembly).

This is probably to agree with Tcl_LreplaceObjCmd, which says on line 2757:

    if ((first >= listLen) && (listLen > 0))

Why does the empty list get this special treatment?


% proc t {s} {lreplace $s 1 end-1}

% t {1 2 3}
1 3

% t {1 2}
1 2

% t {1}
list doesn't contain element 1
    while executing
"lreplace $s 1 end-1"
    (procedure "t" line 1)
    invoked from within
"t {1}"

% t {}      ;# wat?

% ::tcl::unsupported::disassemble proc t
ByteCode 0x0x1cdf640, refCt 1, epoch 54, interp 0x0x1a2bdd0 (epoch 54)
  Source "lreplace $s 1 end-1"
  Cmds 1, src 19, inst 52, litObjs 3, aux 0, stkDepth 3, code/src 0.00
  Proc 0x0x1c7f860, refCt 1, args 1, compiled locals 1
      slot 0, scalar, arg, "s"
  Commands 1:
      1: pc 0-50, src 0-18
  Command 1: "lreplace $s 1 end-1"
    (0) loadScalar1 %v0         # var "s"
    (2) dup 
    (3) listLength 
    (4) push1 0         # "1"
    (6) gt 
    (7) jumpTrue1 +19   # pc 26
*   (9) dup 
*   (10) listLength 
*   (11) jumpFalse1 +15         # pc 26
    (13) push1 1        # "list doesn't contain element 1"
    (15) push1 2        # "-errorcode {TCL OPERATION LREPLACE BADID"...
    (17) returnImm +1 0 
    (26) dup 
    (27) listRangeImm 0 0 
    (36) reverse 2 
    (41) listRangeImm end end 
    (50) listConcat 
    (51) done