Posted to tcl by sebres at Thu May 02 10:14:15 GMT 2019view raw

  1. // http://core.tcl.tk/tdom/info/a858a6ac777f3639
  2.  
  3. // splitTCObjCmd, let objc = 5, then nrArg == 3
  4. // so set and incr evalStub[0 .. 2]
  5. // splitTclImpl, overwrites evalStub[2]
  6. // splitTclImplFree, decr evalStub[0 .. 2], but evalStub[2] is another object here now.
  7.  
  8.  
  9. ---------------------------------------------------------
  10.  
  11.  
  12. static int
  13. splitTclImpl (
  14. Tcl_Interp *interp,
  15. void *constraintData,
  16. char *text
  17. )
  18. {
  19. ...
  20. // nrArg == 3
  21. // ************************************************************************************************
  22. tcdata->evalStub[tcdata->nrArg-1] = Tcl_NewStringObj(text, -1); // ** OVERWRITES evalStub[2] **
  23. // with new object (incr/decr)
  24. // ************************************************************************************************
  25. ...
  26. }
  27.  
  28. static void
  29. splitTclImplFree (
  30. void *constraintData
  31. )
  32. {
  33. ...
  34. // nrArg == 3
  35. for (i = 0; i < tcdata->nrArg-1; i++) { // i iter 0 .. 2
  36. Tcl_DecrRefCount (tcdata->evalStub[i]); // decr evalStub[0 .. 2]
  37. }
  38. ...
  39. }
  40.  
  41. static int
  42. splitTCObjCmd (
  43. ClientData clientData,
  44. Tcl_Interp *interp,
  45. int objc,
  46. Tcl_Obj *const objv[]
  47. )
  48. {
  49. ...
  50. case m_tcl:
  51. sc->constraint = splitTclImpl;
  52. sc->freeData = splitTclImplFree;
  53. tcdata = TMALLOC (splitTclTCData);
  54. // let objc = 5
  55. tcdata->nrArg = objc - 2; // nrArg == 3
  56. tcdata->evalStub = MALLOC (sizeof (Tcl_Obj*) * (objc-1)); // alloc 4
  57. for (i = 2; i < objc; i++) { // i iter 2 .. 4
  58. tcdata->evalStub[i-2] = objv[i]; // set evalStub[0 .. 2] <= objv[2 .. 4]
  59. Tcl_IncrRefCount (tcdata->evalStub[i-2]); // incr evalStub[0 .. 2]
  60. }
  61. tcdata->sdata = sdata;
  62. tcdata->cp = cp;
  63. sc->constraintData = tcdata;
  64. ...
  65. }
  66.