tDOM

Check-in [7fca63fe3f]
Login
Bounty program for improvements to Tcl and certain Tcl packages.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:avoid usage of fallback to __tdomGC at global/NS level, this way it could prevent a leakage of tree in the global var __tdomGC (only affected if current level is global/NS)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | fix-traced-gc-regression-of-091-cr1
Files: files | file ages | folders
SHA3-256: 7fca63fe3fbc8867f273ed8a2f3414a8beb06627cd41603ca83214d02705defb
User & Date: sebres 2019-03-15 15:17:37
Context
2019-03-15
15:17
avoid usage of fallback to __tdomGC at global/NS level, this way it could prevent a leakage of tree in the global var __tdomGC (only affected if current level is global/NS) Leaf check-in: 7fca63fe3f user: sebres tags: fix-traced-gc-regression-of-091-cr1
2019-03-14
16:16
accept tcl-test options like -load "load libtdom...; source ../lib/tdom.tcl" (allow to run test-suite from development environment, other tdom-version or uninstalled) Leaf check-in: 881efc6915 user: sebres tags: fix-traced-gc-regression-of-091
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tcldom.c.

529
530
531
532
533
534
535






















536
537
538
539
540
541
542
...
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569







570
571
572
573
574
575
576
    if (hasTrace) {
        dinfo->document = NULL;
    } else {
        FREE((void*)dinfo);
    }
}























/*----------------------------------------------------------------------------
|   tcldom_docTrace
|
\---------------------------------------------------------------------------*/
static
char * tcldom_docTrace (
................................................................................

    if (doc == NULL || (flags & TCL_TRACE_WRITES)) {
        if (!(flags & (TCL_TRACE_UNSETS|TCL_INTERP_DESTROYED))) {
            Tcl_UntraceVar2(dinfo->interp, name1, name2,
                           TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                           tcldom_docTrace, clientData);
        }
        if (!(flags & TCL_TRACE_WRITES)) {
            FREE (dinfo);
            return NULL;
        }
    }

    DOC_CMD(objCmdName, doc);
    if (flags & TCL_TRACE_WRITES) {







        Tcl_TraceVar2(interp,"__tdomGC", objCmdName, TCL_TRACE_UNSETS,
                     (Tcl_VarTraceProc*)tcldom_docTrace,
                     clientData);
        return NULL;
    }

    DBG(fprintf(stderr, "--> tcldom_docTrace delete doc %p\n", doc));






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







>
>
>
>
>
>
>







529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
...
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
    if (hasTrace) {
        dinfo->document = NULL;
    } else {
        FREE((void*)dinfo);
    }
}

/*----------------------------------------------------------------------------*/

static
int isProcCallFrame(
    Tcl_Interp *interp
) {
    int isproc = 1;
    /* retrieve frame info and check we're at proc-level */
    if (Tcl_Eval(interp, "info frame 0") == TCL_OK) {
        /* check proc is in info-dictionary */
        Tcl_Obj *value, *key = Tcl_NewStringObj("proc", 4);
        if ( Tcl_DictObjGet(NULL, Tcl_GetObjResult(interp), key, &value) != TCL_OK
          || (value == NULL)
        ) {
            /* global or namespace level: */
            isproc = 0;
        };
        Tcl_DecrRefCount(key);
    }
    return isproc;
}

/*----------------------------------------------------------------------------
|   tcldom_docTrace
|
\---------------------------------------------------------------------------*/
static
char * tcldom_docTrace (
................................................................................

    if (doc == NULL || (flags & TCL_TRACE_WRITES)) {
        if (!(flags & (TCL_TRACE_UNSETS|TCL_INTERP_DESTROYED))) {
            Tcl_UntraceVar2(dinfo->interp, name1, name2,
                           TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                           tcldom_docTrace, clientData);
        }
        if (doc == NULL) {
            FREE (dinfo);
            return NULL;
        }
    }

    DOC_CMD(objCmdName, doc);
    if (flags & TCL_TRACE_WRITES) {
        /* avoid usage of fallback to __tdomGC at global/NS level */
        if (!isProcCallFrame(interp)) {
            /* prohibit change (and restore variable) */
            Tcl_SetVar2 (interp, name1, name2, objCmdName, TCL_LEAVE_ERR_MSG);
            return "var is read-only";
        }
        /* save reference in temp GC-array (deleted at end of frame-scope) */
        Tcl_TraceVar2(interp,"__tdomGC", objCmdName, TCL_TRACE_UNSETS,
                     (Tcl_VarTraceProc*)tcldom_docTrace,
                     clientData);
        return NULL;
    }

    DBG(fprintf(stderr, "--> tcldom_docTrace delete doc %p\n", doc));