diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2009-12-08 20:56:28 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2009-12-08 20:56:28 (GMT) |
commit | b475ec90cf97e4e17e2fda2954e1983c882ab339 (patch) | |
tree | f0440b1ff94865fad5e6d9f65c92fec53d2f6615 /generic/tclExecute.c | |
parent | 5291a66f405cc624cacbafb313ad1a5c0e34e3a5 (diff) | |
download | tcl-b475ec90cf97e4e17e2fda2954e1983c882ab339.zip tcl-b475ec90cf97e4e17e2fda2954e1983c882ab339.tar.gz tcl-b475ec90cf97e4e17e2fda2954e1983c882ab339.tar.bz2 |
* generic/tclBasic.c: Partial nre-enabling of coroutines.
* generic/tclExecute.c: The initial call still requires its
* generic/tclInt.h: own instance of tebc, but on resume coros
can execute in the caller's tebc.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index d8cd7f6..039ad24 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -14,7 +14,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.454 2009/12/08 19:00:25 msofer Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.455 2009/12/08 20:56:29 msofer Exp $ */ #include "tclInt.h" @@ -205,6 +205,7 @@ typedef struct BottomData { cleanup = BP->cleanup; \ TAUX.esPtr = iPtr->execEnvPtr->execStackPtr; \ tosPtr = TAUX.esPtr->tosPtr; \ + TAUX.compiledLocals = iPtr->varFramePtr->compiledLocals;\ } while (0) #define PUSH_TAUX_OBJ(objPtr) \ @@ -2006,7 +2007,7 @@ TclExecuteByteCode( iPtr->execEnvPtr->bottomPtr = BP; TAUX.esPtr = iPtr->execEnvPtr->execStackPtr; - TAUX.compiledLocals = iPtr->varFramePtr->compiledLocals;// + TAUX.compiledLocals = iPtr->varFramePtr->compiledLocals; pc = codePtr->codeStart; catchTop = initCatchTop; @@ -2817,15 +2818,17 @@ TclExecuteByteCode( if (param) { codePtr = param; goto nonRecursiveCallStart; + } else { + CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; + + corPtr->callerBP = BP; + goto resumeCoroutine; } - /* NOT CALLED, does not (yet?) work */ - goto resumeCoroutine; - case TCL_NR_TAILCALL_TYPE: - /* - * A request to perform a tailcall: just drop this - * bytecode. - */ - + break; + case TCL_NR_TAILCALL_TYPE: + /* + * A request to perform a tailcall: just drop this + * bytecode. */ #ifdef TCL_COMPILE_DEBUG if (traceInstructions) { fprintf(stdout, " Tailcall request received\n"); @@ -2860,34 +2863,35 @@ TclExecuteByteCode( pc--; goto checkForCatch; } + NRE_ASSERT(iPtr->execEnvPtr == corPtr->eePtr); NRE_ASSERT(corPtr->stackLevel != NULL); NRE_ASSERT(BP == corPtr->eePtr->bottomPtr); if (corPtr->stackLevel != &TAUX) { - Tcl_SetResult(interp, - "cannot yield: C stack busy", TCL_STATIC); - Tcl_SetErrorCode(interp, "TCL", "COROUTINE", - "CANT_YIELD", NULL); + Tcl_SetResult(interp, "cannot yield: C stack busy", + TCL_STATIC); + Tcl_SetErrorCode(interp, "COROUTINE_CANT_YIELD", NULL); TRESULT = TCL_ERROR; pc--; goto checkForCatch; } - + /* * Save our state and return */ - - NR_DATA_BURY(); - TAUX.esPtr->tosPtr = tosPtr; - iPtr->execEnvPtr->bottomPtr = BP; - return TCL_OK; + + corPtr->stackLevel = NULL; /* mark suspended */ + + iPtr->execEnvPtr = corPtr->callerEEPtr; + OBP = corPtr->callerBP; + goto returnToCaller; } default: Tcl_Panic("TEBC: TRCB sent us a callback we cannot handle!"); } } } - + pc += pcAdjustment; nonRecursiveCallReturn: @@ -7448,7 +7452,7 @@ TclExecuteByteCode( statePtr->typePtr = &dictIteratorType; statePtr->internalRep.twoPtrValue.ptr1 = searchPtr; statePtr->internalRep.twoPtrValue.ptr2 = dictPtr; - varPtr = LOCAL(opnd);// + varPtr = LOCAL(opnd); if (varPtr->value.objPtr) { if (varPtr->value.objPtr->typePtr != &dictIteratorType) { TclDecrRefCount(varPtr->value.objPtr); @@ -7971,13 +7975,10 @@ TclExecuteByteCode( NR_DATA_DIG(); if (TOP_CB(interp) == BP->rootPtr) { /* - * The bytecode is returning, all callbacks were run. Remove the - * caller's arguments and keep processing the caller. + * The bytecode is returning, all callbacks were run: keep + * processing the caller. */ - TAUX.esPtr = iPtr->execEnvPtr->execStackPtr; - TAUX.compiledLocals = iPtr->varFramePtr->compiledLocals; - goto nonRecursiveCallReturn; } else { TEOV_callback *callbackPtr = TOP_CB(iPtr); @@ -8009,6 +8010,24 @@ TclExecuteByteCode( } } + /* + * Deal with coros running in the caller's TEBC + */ + + if (iPtr->execEnvPtr->corPtr) { + CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; + /* + * The coro is returning internally iff + * - this is its base TEBC + * - this is it's callers TEBC, signalled by callerBP!=NULL + */ + + OBP = corPtr->callerBP; + if (OBP && (corPtr->stackLevel == &TAUX)) { + goto returnToCaller; + } + } + iPtr->execEnvPtr->bottomPtr = NULL; return TRESULT; } |