Index: TODO =================================================================== diff -u -r0f5513cd0b35c79689a0d04b967ea340577889e8 -r4454585cc13933eceea7815732a3d889e47a0f97 --- TODO (.../TODO) (revision 0f5513cd0b35c79689a0d04b967ea340577889e8) +++ TODO (.../TODO) (revision 4454585cc13933eceea7815732a3d889e47a0f97) @@ -1823,6 +1823,21 @@ - removed debugging from NsfCleanupObject when compiled without DEVELOPMENT - removed debugging from CscFinish when compiled without DEVELOPMENT +- changed CallStackGetActiveProcFrame() to return also CMETHD frames + This allows to execute :volatile in a initcmd and to delete the + object at its end. As a consequence, code like + [CopyHandler new -volatile] copy [::nsf::self] $newName + has to be changed to + CopyHandler new { + :copy [:uplevel ::nsf::self] [uplevel set newName] + :destroy + } + + +- renamed CallStackUseActiveFrames() to CallStackUseActiveFrame() + and ctx->framesSaved to ctx->frameSaved to reflect implementation + + TODO: - "-returns" Index: generic/nsf.c =================================================================== diff -u -r0f5513cd0b35c79689a0d04b967ea340577889e8 -r4454585cc13933eceea7815732a3d889e47a0f97 --- generic/nsf.c (.../nsf.c) (revision 0f5513cd0b35c79689a0d04b967ea340577889e8) +++ generic/nsf.c (.../nsf.c) (revision 4454585cc13933eceea7815732a3d889e47a0f97) @@ -75,7 +75,7 @@ typedef enum { CALLING_LEVEL, ACTIVE_LEVEL } CallStackLevel; typedef struct callFrameContext { - int framesSaved; + int frameSaved; Tcl_CallFrame *framePtr; Tcl_CallFrame *varFramePtr; } callFrameContext; @@ -14754,6 +14754,7 @@ } else /* must be NSF_ARG_METHOD */ { Tcl_Obj *ov[3]; int oc = 0; + if (paramPtr->converterArg) { /* if arg= was given, pass it as first argument */ ov[0] = paramPtr->converterArg; @@ -14820,6 +14821,7 @@ result = CallMethod((ClientData) object, interp, methodObj, remainingArgsc+2, pc.full_objv + i-1, NSF_CSC_IMMEDIATE); } + if (result != TCL_OK) { ParseContextRelease(&pc); goto configure_exit; @@ -14940,7 +14942,7 @@ int result; if (object && (object->filterStack || object->mixinStack) ) { - CallStackUseActiveFrames(interp, &ctx); + CallStackUseActiveFrame(interp, &ctx); } if (!Tcl_Interp_varFramePtr(interp)) { CallStackRestoreSavedFrames(interp, &ctx); @@ -15164,7 +15166,7 @@ } if (object && (object->filterStack || object->mixinStack)) { - CallStackUseActiveFrames(interp, &ctx); + CallStackUseActiveFrame(interp, &ctx); } for ( ; i < objc; i += 2) { @@ -15197,8 +15199,9 @@ fprintf(stderr, "### Can't make objects volatile during shutdown\n"); return NsfVarErrMsg(interp, "Can't make objects volatile during shutdown\n", NULL); } + //NsfShowStack(interp); + CallStackUseActiveFrame(interp, &ctx); - CallStackUseActiveFrames(interp, &ctx); vn = NSTail(fullName); if (Tcl_SetVar2(interp, vn, NULL, fullName, 0)) { Index: generic/nsfStack.c =================================================================== diff -u -r0f5513cd0b35c79689a0d04b967ea340577889e8 -r4454585cc13933eceea7815732a3d889e47a0f97 --- generic/nsfStack.c (.../nsfStack.c) (revision 0f5513cd0b35c79689a0d04b967ea340577889e8) +++ generic/nsfStack.c (.../nsfStack.c) (revision 4454585cc13933eceea7815732a3d889e47a0f97) @@ -221,7 +221,8 @@ if (!(((NsfCallStackContent *)Tcl_CallFrame_clientData(framePtr))->frameType & NSF_CSC_TYPE_INACTIVE)) break; } else { - if (flag & (FRAME_IS_NSF_CMETHOD|FRAME_IS_NSF_OBJECT)) continue; + //if (flag & (FRAME_IS_NSF_CMETHOD|FRAME_IS_NSF_OBJECT)) continue; + if (flag & (FRAME_IS_NSF_OBJECT)) continue; if (flag == 0 || flag & FRAME_IS_PROC) break; } } @@ -344,7 +345,7 @@ /* *---------------------------------------------------------------------- - * NsfCallStackFindActiveFrame -- + * NsfCallStackFindLastInvocation -- * * Find last invocation of a (scripted or nonleaf) method with a * specified offset. @@ -423,7 +424,7 @@ /* *---------------------------------------------------------------------- - * CallStackUseActiveFrames -- + * CallStackUseActiveFrame -- * * Activate the varFrame of the first active non-object frame and * save the previously active frames in the call frame context. @@ -440,12 +441,10 @@ */ static void -CallStackUseActiveFrames(Tcl_Interp *interp, callFrameContext *ctx) { - Tcl_CallFrame - *inFramePtr = (Tcl_CallFrame *)Tcl_Interp_varFramePtr(interp), - *framePtr; +CallStackUseActiveFrame(Tcl_Interp *interp, callFrameContext *ctx) { + Tcl_CallFrame *framePtr, *inFramePtr; - /*NsfCallStackFindActiveFrame(interp, 0, &activeFramePtr);*/ + inFramePtr = (Tcl_CallFrame *)Tcl_Interp_varFramePtr(interp); /* Get the first active non object frame */ framePtr = CallStackGetActiveProcFrame(inFramePtr); @@ -454,12 +453,12 @@ if (inFramePtr == framePtr) { /* call frame pointers are fine */ - ctx->framesSaved = 0; + ctx->frameSaved = 0; } else { ctx->varFramePtr = inFramePtr; - /*fprintf(stderr, "CallStackUseActiveFrames stores %p\n",framePtr);*/ + /*fprintf(stderr, "CallStackUseActiveFrame stores %p\n",framePtr);*/ Tcl_Interp_varFramePtr(interp) = (CallFrame *)framePtr; - ctx->framesSaved = 1; + ctx->frameSaved = 1; } } @@ -469,7 +468,7 @@ * * Restore the previously saved frames from the speficied call * frame context. These frames are typically saved by - * CallStackUseActiveFrames(). + * CallStackUseActiveFrame(). * * Results: * None. @@ -482,7 +481,7 @@ static void CallStackRestoreSavedFrames(Tcl_Interp *interp, callFrameContext *ctx) { - if (ctx->framesSaved) { + if (ctx->frameSaved) { /*fprintf(stderr, "CallStackRestoreSavedFrames drops %p restores %p\n", Tcl_Interp_varFramePtr(interp), ctx->varFramePtr);*/ Tcl_Interp_varFramePtr(interp) = (CallFrame *)ctx->varFramePtr; Index: library/nx/nx.tcl =================================================================== diff -u -rdc2dc691003a7afa24a9c4ec72f91ece7a10d804 -r4454585cc13933eceea7815732a3d889e47a0f97 --- library/nx/nx.tcl (.../nx.tcl) (revision dc2dc691003a7afa24a9c4ec72f91ece7a10d804) +++ library/nx/nx.tcl (.../nx.tcl) (revision 4454585cc13933eceea7815732a3d889e47a0f97) @@ -1273,8 +1273,9 @@ # reused in XOTcl, no "require" there, so use nsf primitiva ::nsf::dispatch $object ::nsf::methods::object::requirenamespace if {$withnew} { - set m [ScopedNew new -volatile \ + set m [ScopedNew new \ -container $object -withclass $class] + $m volatile Class mixin add $m end # TODO: the following is not pretty; however, contains might # build xotcl and next objects. @@ -1427,7 +1428,11 @@ Object public method copy newName { if {[string compare [string trimleft $newName :] [string trimleft [::nsf::self] :]]} { - [CopyHandler new -volatile] copy [::nsf::self] $newName + CopyHandler new { + :copy [:uplevel ::nsf::self] [uplevel set newName] + :destroy + } + #[CopyHandler new -volatile] copy [::nsf::self] $newName } } Index: library/serialize/serializer.tcl =================================================================== diff -u -r6d8e3872bf20cb1ec9ede91101daff85548a46e9 -r4454585cc13933eceea7815732a3d889e47a0f97 --- library/serialize/serializer.tcl (.../serializer.tcl) (revision 6d8e3872bf20cb1ec9ede91101daff85548a46e9) +++ library/serialize/serializer.tcl (.../serializer.tcl) (revision 4454585cc13933eceea7815732a3d889e47a0f97) @@ -410,7 +410,8 @@ :public class-object method deepSerialize {-ignoreVarsRE -ignore -map args} { :resetPattern - set s [:new -childof [::nsf::current object] -volatile] + set s [:new -childof [::nsf::current object]] + $s volatile if {[info exists ignoreVarsRE]} {$s ignoreVarsRE $ignoreVarsRE} if {[info exists ignore]} {$s ignore $ignore} Index: tests/destroy.test =================================================================== diff -u -r6032993b17135284877122cb24dbb65164252934 -r4454585cc13933eceea7815732a3d889e47a0f97 --- tests/destroy.test (.../destroy.test) (revision 6032993b17135284877122cb24dbb65164252934) +++ tests/destroy.test (.../destroy.test) (revision 4454585cc13933eceea7815732a3d889e47a0f97) @@ -622,17 +622,27 @@ # create object Foo create f1 { :bar; :baz; :destroy } - ? {info command f1} "" + ? {info command f1} "" "explicit destroy of object" set c [nx::Class new { :public method bar {} {return 1} :public method baz {} {return 2} - :create new { :bar; :baz; :destroy } + :new { :bar; :baz; :destroy } :destroy }] - ? [list info command $c] "" + ? [list info command $c] "" "explicit destroy of class" + # create new class and object and cleanup everything + set x [nx::Class new { + :volatile + :public method bar {} {return 1} + :public method baz {} {return 2} + :new { :volatile; :bar; :baz } + }] + + ? [list info command $x] "" "destroy via volatile" + } #puts stderr "==== EXIT ===="