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

  1. cannot get {TCL OPERATION LREPLACE BADID} from an empty list
  2.  
  3. There appears to be special bytecode in compiled lreplace so that an empty list
  4. will not trigger the above error (see * in disassembly).
  5.  
  6. This is probably to agree with Tcl_LreplaceObjCmd, which says on line 2757:
  7.  
  8. if ((first >= listLen) && (listLen > 0))
  9.  
  10. Why does the empty list get this special treatment?
  11.  
  12.  
  13. % proc t {s} {lreplace $s 1 end-1}
  14.  
  15. % t {1 2 3}
  16. 1 3
  17.  
  18. % t {1 2}
  19. 1 2
  20.  
  21. % t {1}
  22. list doesn't contain element 1
  23. while executing
  24. "lreplace $s 1 end-1"
  25. (procedure "t" line 1)
  26. invoked from within
  27. "t {1}"
  28.  
  29. % t {} ;# wat?
  30.  
  31. % ::tcl::unsupported::disassemble proc t
  32. ByteCode 0x0x1cdf640, refCt 1, epoch 54, interp 0x0x1a2bdd0 (epoch 54)
  33. Source "lreplace $s 1 end-1"
  34. Cmds 1, src 19, inst 52, litObjs 3, aux 0, stkDepth 3, code/src 0.00
  35. Proc 0x0x1c7f860, refCt 1, args 1, compiled locals 1
  36. slot 0, scalar, arg, "s"
  37. Commands 1:
  38. 1: pc 0-50, src 0-18
  39. Command 1: "lreplace $s 1 end-1"
  40. (0) loadScalar1 %v0 # var "s"
  41. (2) dup
  42. (3) listLength
  43. (4) push1 0 # "1"
  44. (6) gt
  45. (7) jumpTrue1 +19 # pc 26
  46. * (9) dup
  47. * (10) listLength
  48. * (11) jumpFalse1 +15 # pc 26
  49. (13) push1 1 # "list doesn't contain element 1"
  50. (15) push1 2 # "-errorcode {TCL OPERATION LREPLACE BADID"...
  51. (17) returnImm +1 0
  52. (26) dup
  53. (27) listRangeImm 0 0
  54. (36) reverse 2
  55. (41) listRangeImm end end
  56. (50) listConcat
  57. (51) done
  58.  
  59.