Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | merge novem |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dgp-refactor |
Files: | files | file ages | folders |
SHA1: |
408dde56d0b7d5121e5eaf4d315da57f |
User & Date: | dgp 2015-03-24 15:18:11 |
Context
2015-03-24
| ||
18:38 | merge novem check-in: cc8a52a073 user: dgp tags: dgp-refactor | |
15:18 | merge novem check-in: 408dde56d0 user: dgp tags: dgp-refactor | |
15:13 | merge trunk check-in: 199d4d8540 user: dgp tags: novem | |
2015-03-12
| ||
15:07 | merge novem check-in: 6edb8b4e49 user: dgp tags: dgp-refactor | |
Changes
Changes to generic/tcl.h.
︙ | ︙ | |||
57 58 59 60 61 62 63 | #define TCL_MINOR_VERSION 0 #define TCL_RELEASE_LEVEL TCL_ALPHA_RELEASE #define TCL_RELEASE_SERIAL 0 #define TCL_VERSION "9.0" #define TCL_PATCH_LEVEL "9.0a0" | < < < < < < < < < < | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #define TCL_MINOR_VERSION 0 #define TCL_RELEASE_LEVEL TCL_ALPHA_RELEASE #define TCL_RELEASE_SERIAL 0 #define TCL_VERSION "9.0" #define TCL_PATCH_LEVEL "9.0a0" /* * A special definition used to allow this header file to be included from * windows resource files so that they can obtain version information. * RC_INVOKED is defined by default by the windows RC tool. * * Resource compilers don't like all the C stuff, like typedefs and function * declarations, that occur below, so block them out. |
︙ | ︙ |
Changes to generic/tclBasic.c.
︙ | ︙ | |||
3746 3747 3748 3749 3750 3751 3752 | * here, otherwise the pointer to the * requested Command struct to be invoked. */ { Interp *iPtr = (Interp *) interp; /* * data[1] stores a marker for use by tailcalls; it will be set to 1 by | | > | | 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 | * here, otherwise the pointer to the * requested Command struct to be invoked. */ { Interp *iPtr = (Interp *) interp; /* * data[1] stores a marker for use by tailcalls; it will be set to 1 by * command redirectors (imports, alias, ensembles) so that tailcall skips * this callback (that marks the end of the target command) and goes back * to the end of the source command. */ if (iPtr->deferredCallbacks) { iPtr->deferredCallbacks = NULL; } else { TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL); } |
︙ | ︙ | |||
3995 3996 3997 3998 3999 4000 4001 | int result) { Interp *iPtr = (Interp *) interp; iPtr->numLevels--; /* | | | 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 | int result) { Interp *iPtr = (Interp *) interp; iPtr->numLevels--; /* * If there is a tailcall, schedule it next */ if (data[1] && (data[1] != INT2PTR(1))) { TclNRAddCallback(interp, TclNRTailcallEval, data[1], NULL, NULL, NULL); } /* OPT ?? |
︙ | ︙ | |||
7435 7436 7437 7438 7439 7440 7441 | int flags) { return TclNREvalObjv(interp, objc, objv, flags|TCL_EVAL_NOERR, (Command *) cmd); } /***************************************************************************** | | < < < | < > | < | > > | < | < < < < < > < > > > > > | 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 | int flags) { return TclNREvalObjv(interp, objc, objv, flags|TCL_EVAL_NOERR, (Command *) cmd); } /***************************************************************************** * Tailcall related code ***************************************************************************** * * 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). */ void TclMarkTailcall( Tcl_Interp *interp) { Interp *iPtr = (Interp *) interp; |
︙ | ︙ | |||
7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 | 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 | > > > > > > > > > > > > | 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 | 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 |
︙ | ︙ | |||
7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 | } 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[]) { Interp *iPtr = (Interp *) interp; if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?command? ?arg ...?"); return TCL_ERROR; } | > > > > > > > > > > > > > > > > > | | | < | 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 | } 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[]) { Interp *iPtr = (Interp *) interp; if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?command? ?arg ...?"); return TCL_ERROR; } if (!(iPtr->varFramePtr->isProcCallFrame & 1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "tailcall can only be called from a proc, lambda or method", -1)); Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL); return TCL_ERROR; } /* * Invocation without args just clears a scheduled tailcall; invocation * with an argument replaces any previously scheduled tailcall. */ if (iPtr->varFramePtr->tailcallPtr) { Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr); iPtr->varFramePtr->tailcallPtr = NULL; } /* * Create the callback to actually evaluate the tailcalled * command, then set it in the varFrame so that PopCallFrame can use it * at the proper time. */ if (objc > 1) { Tcl_Obj *listPtr, *nsObjPtr; Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr; Tcl_Namespace *ns1Ptr; |
︙ | ︙ | |||
7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 | 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; | > > > > > > > > > > > | 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 | 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; |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
3049 3050 3051 3052 3053 3054 3055 3056 | iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = opnd; iPtr->ensembleRewrite.numInsertedObjs = 1; DECACHE_STACK_INFO(); pc += 6; TEBC_YIELD(); TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL); | > < | 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 | iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = opnd; iPtr->ensembleRewrite.numInsertedObjs = 1; DECACHE_STACK_INFO(); pc += 6; TEBC_YIELD(); TclMarkTailcall(interp); TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL); return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE, NULL, INT_MIN); /* * ----------------------------------------------------------------- * Start of INST_LOAD instructions. * * WARNING: more 'goto' here than your doctor recommended! The different |
︙ | ︙ |
Changes to tests/nre.test.
︙ | ︙ | |||
146 147 148 149 150 151 152 153 154 155 156 157 158 159 | a 0 } -cleanup { rename a {} rename b {} } -constraints { testnrelevels } -result {{0 2 1 1} 0} test nre-5.1 {[namespace eval] is not recursive} -setup { namespace eval ::foo { setabs } proc foo::a i [makebody {namespace eval ::foo [list a $i]}] } -body { | > > > > > > > > > > > > > > > > > > > > > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | a 0 } -cleanup { rename a {} rename b {} } -constraints { testnrelevels } -result {{0 2 1 1} 0} test nre-4.2 {(compiled) ensembles do not break tailcall} -setup { # Fix Bug d87cb18205 proc b {} { tailcall append result first } set map [namespace ensemble configure ::dict -map] dict set map a b namespace ensemble configure ::dict -map $map proc demo {} { dict a append result second } } -body { demo } -cleanup { rename demo {} namespace ensemble configure ::dict -map [dict remove $map a] unset map rename b {} } -result firstsecond test nre-5.1 {[namespace eval] is not recursive} -setup { namespace eval ::foo { setabs } proc foo::a i [makebody {namespace eval ::foo [list a $i]}] } -body { |
︙ | ︙ |
Changes to tests/tailcall.test.
︙ | ︙ | |||
142 143 144 145 146 147 148 149 150 151 152 153 154 155 | namespace ensemble create -command a -map {b b} } -body { a b 0 } -cleanup { rename a {} rename b {} } -result {0 0 0 0 0 0} test tailcall-0.6 {tailcall is constant space} -constraints {testnrelevels knownBug} -setup { # # This test fails because ns-unknown is not NR-enabled # proc c i { if {$i == 1} { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | namespace ensemble create -command a -map {b b} } -body { a b 0 } -cleanup { rename a {} rename b {} } -result {0 0 0 0 0 0} test tailcall-0.5.1 {tailcall is constant space} -constraints testnrelevels -setup { # # This test is related to [bug d87cb182053fd79b3]: the fix to that bug was # to remove a call to TclSkipTailcall, which caused a violation of the # constant-space property of tailcall in that particular # configuration. This test was added to detect that, and insure that the # problem is fixed. # proc b i { if {$i == 1} { depthDiff } if {[incr i] > 10} { return [depthDiff] } tailcall dict b $i } set map0 [namespace ensemble configure dict -map] set map $map0 dict set map b b namespace ensemble configure dict -map $map } -body { dict b 0 } -cleanup { rename b {} namespace ensemble configure dict -map $map0 unset map map0 } -result {0 0 0 0 0 0} test tailcall-0.6 {tailcall is constant space} -constraints {testnrelevels knownBug} -setup { # # This test fails because ns-unknown is not NR-enabled # proc c i { if {$i == 1} { |
︙ | ︙ |
Changes to win/tclAppInit.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tcl.h" #define WIN32_LEAN_AND_MEAN #include <windows.h> #undef WIN32_LEAN_AND_MEAN #include <locale.h> #include <stdlib.h> #include <tchar.h> #ifdef TCL_TEST extern Tcl_PackageInitProc Tcltest_Init; | > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tcl.h" #define WIN32_LEAN_AND_MEAN #define STRICT /* See MSDN Article Q83456 */ #include <windows.h> #undef STRICT #undef WIN32_LEAN_AND_MEAN #include <locale.h> #include <stdlib.h> #include <tchar.h> #ifdef TCL_TEST extern Tcl_PackageInitProc Tcltest_Init; |
︙ | ︙ |
Changes to win/tclWinConsole.c.
︙ | ︙ | |||
216 217 218 219 220 221 222 | DWORD nbytes, LPDWORD nbytesread) { DWORD ntchars; BOOL result; int tcharsize = sizeof(TCHAR); | > > > > > > > > > > > | | > | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | DWORD nbytes, LPDWORD nbytesread) { DWORD ntchars; BOOL result; int tcharsize = sizeof(TCHAR); /* * If user types a Ctrl-Break or Ctrl-C, ReadConsole will return * success with ntchars == 0 and GetLastError() will be * ERROR_OPERATION_ABORTED. We do not want to treat this case * as EOF so we will loop around again. If no Ctrl signal handlers * have been established, the default signal OS handler in a separate * thread will terminate the program. If a Ctrl signal handler * has been established (through an extension for example), it * will run and take whatever action it deems appropriate. */ do { result = ReadConsole(hConsole, lpBuffer, nbytes / tcharsize, &ntchars, NULL); } while (result && ntchars == 0 && GetLastError() == ERROR_OPERATION_ABORTED); if (nbytesread != NULL) { *nbytesread = ntchars * tcharsize; } return result; } static BOOL |
︙ | ︙ |