Notes on the first of [Miguel Sofer]'s talks about NRE. (Please add/enhance/correct ...) State of computation in 8.5 * C-stack (1 per thread) * Nesting of C-function calls * CallFrame stack (1 per interp) * Nesting of [proc], [apply], [namespace eval]; this is what [upvar] and [uplevel] navigate * Tcl Evaluation Stack (1 per execEnv/interp) * Bytecode engine stack and workspace * Special allocator supported (TclStacAlloc) * CmdFrameStack (1 per interpereter) Walked through a simplified stack trace of: proc foo {} { set x 1 moo set x 2 } proc moo {} { set x 1 puts $x; # WE ARE HERE set x 2 } Above will have 3 instances of TclExecuteByteCode; full stack 16 levels deep Stack overflow and recursion limits: Some platforms (BSD and other Unixes) have small default stack; Stack-hungry platforms (i.e., Windows debug builds); Severely stack constrained platforms (Cisco, phones?). mod-8-3-branch created a few years ago by ActiveState for a customer. The C stack in 8.6: above example only has 1 instance of TclExecuteByteCode(!) Barring any undiscovered bugs, full compatability. Only additions to the API, no changes. Modification of struct Command, changes to Tcl_GetCommandInfo/TclSetCommandInfo designed not to break extensions that call*objectProc directly. Changed structs (extended): Interp, Command, ExecEnv. Extensions that include internal private headers might break, but that is what they deserve. New C API (TIP #322): * Tcl_NRCreateCommand * Tcl_NREvalObj * Tcl_NREvalObjv * Tcl_NRCmdSwap * Tcl_NRAddCallback An NRE-enabled command requires two implementations: the regular objProc and a new nreProc. NRE provides a utility function Tcl_NRCallObjProc to make this task essentially trivial. If he could have prohibited people from calling the objProc implementation directly a separate nreProc would not be necessary, but it is to maintain maximum compatability with existing extensions. int MyCmdObjProc( ... ) { result = ... ... } After adaptation looks like: int MyCmdNreProc( ... ) { Tcl_NRAddCallback(interp, MyPostProc, data0, data1, NULL, NULL); return Tcl_NREvalObj(interp, objPtr, flags); } int MyPostProc( ... ) { Tcl_Obj *fooPtr = data[0]; /* data0 retrieved */ MyStruct *mooPtr = data[1]; /* data1 retrieved */ return = result; ... } ---- !!!!!! %| [Tcl 2008 Conference Talks] |% !!!!!!