Tcl Source Code

View Ticket
Login
Ticket UUID: 2649975
Title: bizarre interaction of uplevel and tailcall
Type: Bug Version: obsolete: 8.6b1.1
Submitter: kennykb Created on: 2009-02-28 23:20:34
Subsystem: 35. TclOO Package Assigned To: msofer
Priority: 8 Severity:
Status: Closed Last Modified: 2009-03-20 06:34:40
Resolution: Fixed Closed By: msofer
    Closed on: 2009-03-19 23:34:40
Description:
I'm struggling to come up with a smaller example of this
problem; it's quite nasty.

When the attached 'bugg.tcl' script is run, it
produces the output,

v should have been found at global level but was found in bar's method bravo

Removing the line:

proc dump args {}

from the script makes it print a play-by-play analysis of what happened.

It appears that everything is working fine right up to the very end, when the last [tailcall] invokes

::grill create betty

That constructor runs at level 2, despite having been tailcalled from level 1, and causing [upvar 1 v w] to resolve in the wrong callframe.
User Comments: msofer added on 2009-03-20 06:34:40:

allow_comments - 1

These two examples were added to tests/tailcall.test

dkf added on 2009-03-17 16:17:35:
Having slept on it, I think the issue is related to the fact that TclNREvalObjEx-list doesn't push the same callbacks as TclNREvalObjEx-string. Respectively:

  TclNREvalObjEx-list:
    TEOEx_ListCallback
    NRCommand
    NRRunObjProc

  TclNREvalObjEx-string:
    TEOEx_ByteCodeCallback
    NRCallTEBC

According to what I can (and can't) see in the code, the issue might be that NRCommand doesn't do tailcall processing; that's only done in TEBC (which doesn't get called at this level on the canonical-list route).

dkf added on 2009-03-17 06:24:05:
problem seems to be that tailcall doesn't work right from within a procedure called by a pure-list uplevel body

dkf added on 2009-03-17 06:21:29:

File Deleted - 318108: 



File Added - 318114: bug2.tcl

This version also exhibits the bug and doesn't use TclOO...
File Added: bug2.tcl

dkf added on 2009-03-17 05:50:08:
Evidence! In my script, in procedure 'bravo', changing
    uplevel 1 [list delta ::betty]
to
    uplevel 1 delta ::betty
makes the problem go away.

dkf added on 2009-03-17 05:38:01:

File Added - 318108: bug2.tcl

Here's a simplified version that exhibits the same problem, but with less gunk in the way.

Note that it does not include the puzzling code from the original that wasn't hitting the problem...
File Added: bug2.tcl

dkf added on 2009-03-16 20:42:59:
Confirmed with HEAD. At the offending point (just before doing 'set resolution $w' in grill's constructor) doing an 'uplevel 1 dump' produces this output:
  1: ::barney bravo
That would seem to indicate that we're somehow managing to not stick within the constraints of the [uplevel]ed stack! I have no idea at all how that could possibly happen! Help!

kennykb added on 2009-03-01 06:20:35:

File Added - 315619: bugg.tcl

Attachments: