diff options
author | mig <mig> | 2012-12-06 02:17:40 (GMT) |
---|---|---|
committer | mig <mig> | 2012-12-06 02:17:40 (GMT) |
commit | e239bd28968f855bcade0481a44082490dcb4b33 (patch) | |
tree | de6ede1b7b0808e44d2e1f9cc875b8b0ee82b392 /generic | |
parent | d5c1f667736fc5d77a622d358a4f2aa954f96f95 (diff) | |
download | tcl-e239bd28968f855bcade0481a44082490dcb4b33.zip tcl-e239bd28968f855bcade0481a44082490dcb4b33.tar.gz tcl-e239bd28968f855bcade0481a44082490dcb4b33.tar.bz2 |
Fix [tailcall] and [yieldto] to not panic in dying namespaces: [Bug 3592747]bug_3592747
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclBasic.c | 45 | ||||
-rw-r--r-- | generic/tclExecute.c | 9 |
2 files changed, 19 insertions, 35 deletions
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); /* |