summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormig <mig>2012-12-06 02:17:40 (GMT)
committermig <mig>2012-12-06 02:17:40 (GMT)
commite239bd28968f855bcade0481a44082490dcb4b33 (patch)
treede6ede1b7b0808e44d2e1f9cc875b8b0ee82b392
parentd5c1f667736fc5d77a622d358a4f2aa954f96f95 (diff)
downloadtcl-bug_3592747.zip
tcl-bug_3592747.tar.gz
tcl-bug_3592747.tar.bz2
Fix [tailcall] and [yieldto] to not panic in dying namespaces: [Bug 3592747]bug_3592747
-rw-r--r--ChangeLog5
-rw-r--r--generic/tclBasic.c45
-rw-r--r--generic/tclExecute.c9
3 files changed, 24 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 6f8c8ae..876fc1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2012-12-05 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c: Fix [tailcall] and [yieldto] to not panic
+ * generic/tclExecute.c: in dying namespaces: [Bug 3592747]
+
2012-11-28 Donal K. Fellows <dkf@users.sf.net>
* generic/tclZlib.c (ZlibStreamSubcmd): [Bug 3590483]: Use a mechanism
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 562cca6..bded338 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -8333,22 +8333,16 @@ TclNRTailcallObjCmd(
*/
if (objc > 1) {
- Tcl_Obj *listPtr, *nsObjPtr;
- Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
- Tcl_Namespace *ns1Ptr;
+ Tcl_Obj *listPtr;
+ Namespace *nsPtr = iPtr->varFramePtr->nsPtr;
NRE_callback *tailcallPtr;
listPtr = Tcl_NewListObj(objc-1, objv+1);
Tcl_IncrRefCount(listPtr);
- nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
- if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
- || (nsPtr != ns1Ptr)) {
- Tcl_Panic("Tailcall failed to find the proper namespace");
- }
- Tcl_IncrRefCount(nsObjPtr);
+ nsPtr->refCount++;
- TclNRAddCallback(interp, TclNRTailcallEval, listPtr, nsObjPtr,
+ TclNRAddCallback(interp, TclNRTailcallEval, listPtr, nsPtr,
NULL, NULL);
tailcallPtr = TOP_CB(interp);
TOP_CB(interp) = tailcallPtr->nextPtr;
@@ -8365,19 +8359,14 @@ TclNRTailcallEval(
{
Interp *iPtr = (Interp *) interp;
Tcl_Obj *listPtr = data[0];
- Tcl_Obj *nsObjPtr = data[1];
- Tcl_Namespace *nsPtr;
+ Namespace *nsPtr = data[1];
int objc;
Tcl_Obj **objv;
- if (result == TCL_OK) {
- result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
- }
-
if (result != TCL_OK) {
/*
- * Tailcall execution was preempted, eg by an intervening catch or by
- * a now-gone namespace: cleanup and return.
+ * Tailcall execution was preempted, eg by an intervening catch:
+ * cleanup and return.
*/
TailcallCleanup(data, interp, result);
@@ -8388,8 +8377,8 @@ TclNRTailcallEval(
* Perform the tailcall
*/
- TclNRDeferCallback(interp, TailcallCleanup, listPtr, nsObjPtr, NULL,NULL);
- iPtr->lookupNsPtr = (Namespace *) nsPtr;
+ TclNRDeferCallback(interp, TailcallCleanup, listPtr, nsPtr, NULL,NULL);
+ iPtr->lookupNsPtr = nsPtr;
ListObjGetElements(listPtr, objc, objv);
return TclNREvalObjv(interp, objc, objv, 0, NULL);
}
@@ -8401,7 +8390,7 @@ TailcallCleanup(
int result)
{
Tcl_DecrRefCount((Tcl_Obj *) data[0]);
- Tcl_DecrRefCount((Tcl_Obj *) data[1]);
+ TclNsDecrRefCount((Namespace *) data[1]);
return result;
}
@@ -8493,9 +8482,8 @@ TclNRYieldToObjCmd(
Tcl_Obj *const objv[])
{
CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
- Tcl_Obj *listPtr, *nsObjPtr;
- Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
- Tcl_Namespace *ns1Ptr;
+ Tcl_Obj *listPtr;
+ Namespace *nsPtr = iPtr->varFramePtr->nsPtr;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "command ?arg ...?");
@@ -8518,19 +8506,14 @@ TclNRYieldToObjCmd(
listPtr = Tcl_NewListObj(objc-1, objv+1);
Tcl_IncrRefCount(listPtr);
- nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
- if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
- || (nsPtr != ns1Ptr)) {
- Tcl_Panic("yieldto failed to find the proper namespace");
- }
- Tcl_IncrRefCount(nsObjPtr);
+ nsPtr->refCount++;
/*
* Add the callback in the caller's env, then instruct TEBC to yield.
*/
iPtr->execEnvPtr = corPtr->callerEEPtr;
- TclNRAddCallback(interp, YieldToCallback, corPtr, listPtr, nsObjPtr,
+ TclNRAddCallback(interp, YieldToCallback, corPtr, listPtr, nsPtr,
NULL);
iPtr->execEnvPtr = corPtr->eePtr;
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 2b5f713..b04cdf6 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -2375,7 +2375,8 @@ TEBCresume(
}
case INST_TAILCALL: {
- Tcl_Obj *listPtr, *nsObjPtr;
+ Tcl_Obj *listPtr;
+ Namespace *nsPtr;
NRE_callback *tailcallPtr;
opnd = TclGetUInt1AtPtr(pc+1);
@@ -2409,10 +2410,10 @@ TEBCresume(
*/
listPtr = Tcl_NewListObj(opnd, &OBJ_AT_DEPTH(opnd-1));
- nsObjPtr = Tcl_NewStringObj(iPtr->varFramePtr->nsPtr->fullName, -1);
+ nsPtr = iPtr->varFramePtr->nsPtr;
Tcl_IncrRefCount(listPtr);
- Tcl_IncrRefCount(nsObjPtr);
- TclNRAddCallback(interp, TclNRTailcallEval, listPtr, nsObjPtr,
+ nsPtr->refCount++;
+ TclNRAddCallback(interp, TclNRTailcallEval, listPtr, nsPtr,
NULL, NULL);
/*