Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | more comments |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | mig-tailcall-cleanup |
Files: | files | file ages | folders |
SHA1: |
8ef09a1e8a1a6c7f6e7131ce31801360 |
User & Date: | msofer 2015-03-23 13:43:37 |
Context
2015-03-23
| ||
13:46 | fix comments describing tailcall implementation check-in: 654bad187e user: msofer tags: trunk | |
13:43 | more comments Closed-Leaf check-in: 8ef09a1e8a user: msofer tags: mig-tailcall-cleanup | |
02:11 | updated, improved tailcall comments check-in: cf96e3ae67 user: msofer tags: mig-tailcall-cleanup | |
Changes
Changes to generic/tclBasic.c.
︙ | ︙ | |||
8177 8178 8179 8180 8181 8182 8183 | * The steps of the tailcall dance are as follows: * * 1. when [tailcall] is invoked, it stores the corresponding callback in * the current CallFrame and returns TCL_RETURN * 2. when the CallFrame is popped, it calls TclSetTailcall to store the * callback in the proper NRCommand callback - the spot where the command * that pushed the CallFrame is completely cleaned up | > | < | 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 | * The steps of the tailcall dance are as follows: * * 1. when [tailcall] is invoked, it stores the corresponding callback in * the current CallFrame and returns TCL_RETURN * 2. when the CallFrame is popped, it calls TclSetTailcall to store the * callback in the proper NRCommand callback - the spot where the command * that pushed the CallFrame is completely cleaned up * 3. when the NRCommand callback runs, it schedules the tailcall callback * to run immediately after it returns * * One delicate point is to properly define the NRCommand where the tailcall * will execute. There are functions whose purpose is to help define the * precise spot: TclMarkTailcall ("this is the spot") and TclSkipTailcall * ("skip the next command: we are redirecting to it, tailcalls should run * after WE return"), TclPushTailcallPoint (special for OO). */ |
︙ | ︙ | |||
8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 | TclPushTailcallPoint( Tcl_Interp *interp) { TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL); ((Interp *) interp)->numLevels++; } void TclSetTailcall( Tcl_Interp *interp, Tcl_Obj *listPtr) { /* * Find the splicing spot: right before the NRCommand of the thing | > > > > > > > > > > > > | 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 | TclPushTailcallPoint( Tcl_Interp *interp) { TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL); ((Interp *) interp)->numLevels++; } /* *---------------------------------------------------------------------- * * TclSetTailcall -- * * Splice a tailcall command in the proper spot of the NRE callback * stack, so that it runs at the right time. * *---------------------------------------------------------------------- */ void TclSetTailcall( Tcl_Interp *interp, Tcl_Obj *listPtr) { /* * Find the splicing spot: right before the NRCommand of the thing |
︙ | ︙ | |||
8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 | } if (!runPtr) { Tcl_Panic("tailcall cannot find the right splicing spot: should not happen!"); } runPtr->data[1] = listPtr; } int TclNRTailcallObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { | > > > > > > > > > > > > > > > > > | 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 | } if (!runPtr) { Tcl_Panic("tailcall cannot find the right splicing spot: should not happen!"); } runPtr->data[1] = listPtr; } /* *---------------------------------------------------------------------- * * TclNRTailcallObjCmd -- * * Prepare the tailcall as a list and store it in the current * varFrame. When the frame is later popped the tailcall will be spliced * at the proper place. * * Results: * The first NRCommand callback that is not marked to be skipped is * updated so that its data[1] field contains the tailcall list. * *---------------------------------------------------------------------- */ int TclNRTailcallObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { |
︙ | ︙ | |||
8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 | TclListObjSetElement(interp, listPtr, 0, nsObjPtr); iPtr->varFramePtr->tailcallPtr = listPtr; } return TCL_RETURN; } int TclNRTailcallEval( ClientData data[], Tcl_Interp *interp, int result) { Interp *iPtr = (Interp *) interp; | > > > > > > > > > > > | 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 | TclListObjSetElement(interp, listPtr, 0, nsObjPtr); iPtr->varFramePtr->tailcallPtr = listPtr; } return TCL_RETURN; } /* *---------------------------------------------------------------------- * * TclNRTailcallEval -- * * This NREcallback actually causes the tailcall to be evaluated. * *---------------------------------------------------------------------- */ int TclNRTailcallEval( ClientData data[], Tcl_Interp *interp, int result) { Interp *iPtr = (Interp *) interp; |
︙ | ︙ |