diff options
| author | pooryorick <com.digitalsmarties@pooryorick.com> | 2021-06-20 22:47:14 (GMT) |
|---|---|---|
| committer | pooryorick <com.digitalsmarties@pooryorick.com> | 2021-06-20 22:47:14 (GMT) |
| commit | 70c2b0e817830a7baec1796e3dc095fba8b7f6f8 (patch) | |
| tree | 8b0cef2088c910f8a9f42a2f552d8dda9caf4ed5 /generic/tclBasic.c | |
| parent | 55076a6af2828fbde128302729c1878a573412a7 (diff) | |
| download | tcl-70c2b0e817830a7baec1796e3dc095fba8b7f6f8.zip tcl-70c2b0e817830a7baec1796e3dc095fba8b7f6f8.tar.gz tcl-70c2b0e817830a7baec1796e3dc095fba8b7f6f8.tar.bz2 | |
Fix for [f9800d52bd61f240], vwait is not NRE-enabled, and yieldto cannot find
the right splicing spot
Diffstat (limited to 'generic/tclBasic.c')
| -rw-r--r-- | generic/tclBasic.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 86d7960..69194f8 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -4866,6 +4866,7 @@ NRCommand( int result) { Interp *iPtr = (Interp *) interp; + Tcl_Obj *listPtr; iPtr->numLevels--; @@ -4874,7 +4875,10 @@ NRCommand( */ if (data[1] && (data[1] != INT2PTR(1))) { - TclNRAddCallback(interp, TclNRTailcallEval, data[1], NULL, NULL, NULL); + listPtr = (Tcl_Obj *)data[1]; + data[1] = NULL; + + TclNRAddCallback(interp, TclNRTailcallEval, listPtr, NULL, NULL, NULL); } /* OPT ?? @@ -9449,6 +9453,7 @@ TclNRYieldToObjCmd( iPtr->execEnvPtr = corPtr->callerEEPtr; TclSetTailcall(interp, listPtr); + corPtr->yieldPtr = listPtr; iPtr->execEnvPtr = corPtr->eePtr; return TclNRYieldObjCmd(INT2PTR(CORO_ACTIVATE_YIELDM), interp, 1, objv); @@ -9646,6 +9651,22 @@ TclNRCoroutineActivateCallback( */ if (corPtr->stackLevel != stackLevel) { + NRE_callback *runPtr; + + iPtr->execEnvPtr = corPtr->callerEEPtr; + if (corPtr->yieldPtr) { + for (runPtr = TOP_CB(interp); runPtr; runPtr = runPtr->nextPtr) { + if (runPtr->data[1] == corPtr->yieldPtr) { + runPtr->data[1] = NULL; + Tcl_DecrRefCount(corPtr->yieldPtr); + corPtr->yieldPtr = NULL; + break; + } + } + } + iPtr->execEnvPtr = corPtr->eePtr; + + Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot yield: C stack busy", -1)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "CANT_YIELD", @@ -9661,6 +9682,7 @@ TclNRCoroutineActivateCallback( Tcl_Panic("Yield received an option which is not implemented"); } + corPtr->yieldPtr = NULL; corPtr->stackLevel = NULL; numLevels = iPtr->numLevels; |
