summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2014-01-22 09:07:45 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2014-01-22 09:07:45 (GMT)
commit78a75740ae5c82cc161e49e5e28a306fa9f2a580 (patch)
treec400df162e6d42778aee67fd8f71e5fcb0d383d2 /generic
parent61bfac2613d3cc063099ad9e6de3110491b6f5df (diff)
downloadtcl-78a75740ae5c82cc161e49e5e28a306fa9f2a580.zip
tcl-78a75740ae5c82cc161e49e5e28a306fa9f2a580.tar.gz
tcl-78a75740ae5c82cc161e49e5e28a306fa9f2a580.tar.bz2
[a90d9331bc]: must not crash when yieldto called in vanishing namespace
Diffstat (limited to 'generic')
-rw-r--r--generic/tclBasic.c18
-rw-r--r--generic/tclExecute.c11
2 files changed, 18 insertions, 11 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index e355229..cb9428c 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -8431,11 +8431,13 @@ TclNRYieldToObjCmd(
return TCL_ERROR;
}
- /*
- * Add the tailcall in the caller env, then just yield.
- *
- * This is essentially code from TclNRTailcallObjCmd
- */
+ if (((Namespace *) TclGetCurrentNamespace(interp))->flags & NS_DYING) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "yieldto called in deleted namespace", -1));
+ Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "YIELDTO_IN_DELETED",
+ NULL);
+ return TCL_ERROR;
+ }
/*
* Add the tailcall in the caller env, then just yield.
@@ -8444,15 +8446,9 @@ TclNRYieldToObjCmd(
*/
listPtr = Tcl_NewListObj(objc, objv);
-
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
- if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
- || (nsPtr != ns1Ptr)) {
- Tcl_Panic("yieldto failed to find the proper namespace");
- }
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
-
/*
* Add the callback in the caller's env, then instruct TEBC to yield.
*/
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 575f227..6749120 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -2542,6 +2542,17 @@ TEBCresume(
CACHE_STACK_INFO();
goto gotError;
}
+ if (((Namespace *)TclGetCurrentNamespace(interp))->flags & NS_DYING) {
+ TRACE(("[%.30s] => ERROR: yield in deleted\n",
+ O2S(valuePtr)));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "yieldto called in deleted namespace", -1));
+ DECACHE_STACK_INFO();
+ Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "YIELDTO_IN_DELETED",
+ NULL);
+ CACHE_STACK_INFO();
+ goto gotError;
+ }
#ifdef TCL_COMPILE_DEBUG
if (tclTraceExec >= 2) {