Index: TODO =================================================================== diff -u -r6c2e8f94be1ba335ff90d4b6b5132c98a9f5c242 -r937992852d688bc487c8f59273dfa045d077a9c8 --- TODO (.../TODO) (revision 6c2e8f94be1ba335ff90d4b6b5132c98a9f5c242) +++ TODO (.../TODO) (revision 937992852d688bc487c8f59273dfa045d077a9c8) @@ -1801,6 +1801,12 @@ - implemented exported command ::nsf::self as fast conveniance replacement for "::nsf::current object". +- removed bug-alert from nx.tcl (wrong false-positives for + compiled locals in slots) +- added a few small optimization. nsf appears to run on + the shootout benchmark the same speed like a year ago + (which much less functionality) + TODO: - "-returns" Index: generic/gentclAPI.tcl =================================================================== diff -u -r7a6e32605412db15c6b9a1d61ce0a9dfd92bfbf6 -r937992852d688bc487c8f59273dfa045d077a9c8 --- generic/gentclAPI.tcl (.../gentclAPI.tcl) (revision 7a6e32605412db15c6b9a1d61ce0a9dfd92bfbf6) +++ generic/gentclAPI.tcl (.../gentclAPI.tcl) (revision 937992852d688bc487c8f59273dfa045d077a9c8) @@ -193,6 +193,17 @@ } proc genStub {stub intro obj idx cDefs pre call post} { + # Tiny optimization for calls without parameters; + # ParseContextExtendObjv() is just called for procs, so no need to + # free non-static objvs. Actually, the api for c-methods does + # not allow to generate structures which have to be freed. + # we assert this in the code. + if {$cDefs ne ""} { + set releasePC "ParseContextRelease(&pc);" + set releasePC "assert(pc.status == 0);" + } else { + set releasePC "" + } return [subst -nocommands { static int ${stub}(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { @@ -206,7 +217,7 @@ } else { $cDefs $pre - ParseContextRelease(&pc); + $releasePC $call $post } Index: generic/nsf.c =================================================================== diff -u -r6c2e8f94be1ba335ff90d4b6b5132c98a9f5c242 -r937992852d688bc487c8f59273dfa045d077a9c8 --- generic/nsf.c (.../nsf.c) (revision 6c2e8f94be1ba335ff90d4b6b5132c98a9f5c242) +++ generic/nsf.c (.../nsf.c) (revision 937992852d688bc487c8f59273dfa045d077a9c8) @@ -145,7 +145,7 @@ int flags_static[PARSE_CONTEXT_PREALLOC+1]; int lastobjc; int objc; - int mustDecr; + int status; int varArgs; NsfObject *object; } ParseContext; @@ -184,11 +184,10 @@ static int NsfOConfigureMethod(Tcl_Interp *interp, NsfObject *object, int objc, Tcl_Obj *CONST objv[]); static int NsfODestroyMethod(Tcl_Interp *interp, NsfObject *object); static int NsfOResidualargsMethod(Tcl_Interp *interp, NsfObject *object, int objc, Tcl_Obj *CONST objv[]); -// TODO remove last arg of methoddispatch static int MethodDispatch(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Command cmd, NsfObject *object, NsfClass *cl, - CONST char *methodName, int frameType, int flags, int call); + CONST char *methodName, int frameType, int flags); static int DispatchDefaultMethod(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int flags); static int DispatchDestroyMethod(Tcl_Interp *interp, NsfObject *object, int flags); @@ -200,7 +199,7 @@ Tcl_Obj *CONST objv[], int flags); //TODO remove string, methodName NSF_INLINE static int ObjectDispatchFinalize(Tcl_Interp *interp, NsfCallStackContent *cscPtr, - int result, char *string, CONST char *methodName); + int result /*, char *string , CONST char *methodName*/); /* prototypes for object life-cycle management */ static int RecreateObject(Tcl_Interp *interp, NsfClass *cl, NsfObject *object, int objc, Tcl_Obj *CONST objv[]); @@ -241,7 +240,7 @@ /* prototypes for call stack specific calls */ NSF_INLINE static void CscInit(NsfCallStackContent *cscPtr, NsfObject *object, NsfClass *cl, - Tcl_Command cmd, int frameType, int flags, char *msg); + Tcl_Command cmd, unsigned short frameType, unsigned short flags); NSF_INLINE static void CscFinish(Tcl_Interp *interp, NsfCallStackContent *cscPtr, char *string); NSF_INLINE static void CallStackDoDestroy(Tcl_Interp *interp, NsfObject *object); @@ -290,6 +289,7 @@ pcPtr->full_objv = &pcPtr->objv_static[0]; pcPtr->clientData = &pcPtr->clientData_static[0]; pcPtr->flags = &pcPtr->flags_static[0]; + pcPtr->status = 0; } else { pcPtr->full_objv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj*)*(objc+1)); pcPtr->flags = (int*)ckalloc(sizeof(int)*(objc+1)); @@ -298,12 +298,13 @@ memset(pcPtr->full_objv, 0, sizeof(Tcl_Obj*)*(objc+1)); memset(pcPtr->flags, 0, sizeof(int)*(objc+1)); memset(pcPtr->clientData, 0, sizeof(ClientData)*(objc)); + pcPtr->status = NSF_PC_STATUS_FREE_OBJV|NSF_PC_STATUS_FREE_CD; } pcPtr->objv = &pcPtr->full_objv[1]; pcPtr->full_objv[0] = procName; pcPtr->object = object; pcPtr->varArgs = 0; - pcPtr->mustDecr = 0; + } static void @@ -318,6 +319,7 @@ pcPtr->full_objv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj*) * requiredSize); memcpy(pcPtr->full_objv, &pcPtr->objv_static[0], sizeof(Tcl_Obj*) * PARSE_CONTEXT_PREALLOC); /*fprintf(stderr, "alloc %d new objv=%p pcPtr %p\n", requiredSize, pcPtr->full_objv, pcPtr);*/ + pcPtr->status |= NSF_PC_STATUS_FREE_OBJV; } else { /* realloc from mallocated memory */ pcPtr->full_objv = (Tcl_Obj **)ckrealloc((char *)pcPtr->full_objv, sizeof(Tcl_Obj*) * requiredSize); @@ -334,26 +336,30 @@ static void ParseContextRelease(ParseContext *pcPtr) { - if (pcPtr->mustDecr) { - int i; - for (i = 0; i < pcPtr->lastobjc; i++) { - if (pcPtr->flags[i] & NSF_PC_MUST_DECR) { - DECR_REF_COUNT(pcPtr->objv[i]); + int status = pcPtr->status; + + if (status) { + if (status & NSF_PC_STATUS_MUST_DECR) { + int i; + for (i = 0; i < pcPtr->lastobjc; i++) { + if (pcPtr->flags[i] & NSF_PC_MUST_DECR) { + DECR_REF_COUNT(pcPtr->objv[i]); + } } } + + /* objv can be separately extended */ + if (status & NSF_PC_STATUS_FREE_OBJV) { + /*fprintf(stderr, "ParseContextRelease %p free %p %p\n", pcPtr, pcPtr->full_objv, pcPtr->clientData);*/ + ckfree((char *)pcPtr->full_objv); + } + /* if the parameter definition was extended, both clientData and flags are extended */ + if (status & NSF_PC_STATUS_FREE_CD) { + /*fprintf(stderr, "free clientdata and flags\n");*/ + ckfree((char *)pcPtr->clientData); + ckfree((char *)pcPtr->flags); + } } - - /* objv can be separately extended */ - if (pcPtr->objv != &pcPtr->objv_static[1]) { - /*fprintf(stderr, "ParseContextRelease %p free %p %p\n", pcPtr, pcPtr->full_objv, pcPtr->clientData);*/ - ckfree((char *)pcPtr->full_objv); - } - /* if the parameter definition was extended, both clientData and flags are extended */ - if (pcPtr->clientData != &pcPtr->clientData_static[0]) { - /*fprintf(stderr, "free clientdata and flags\n");*/ - ckfree((char *)pcPtr->clientData); - ckfree((char *)pcPtr->flags); - } } /* @@ -2178,7 +2184,7 @@ NsfObject *object = cscPtr ? cscPtr->self : NULL; TclVarHashTable *varTablePtr; Tcl_Var var = resVarInfo->var; - int new, flags = var ? ((Var*)var)->flags : 0; + int new; #if defined(VAR_RESOLVER_TRACE) fprintf(stderr,"CompiledColonVarFetch var '%s' var %p flags = %.4x dead? %.4x\n", @@ -2191,13 +2197,13 @@ * */ - if (object == resVarInfo->lastObject && ((flags & VAR_DEAD_HASH)) == 0) { + if (var && object == resVarInfo->lastObject && (((((Var*)var)->flags) & VAR_DEAD_HASH)) == 0) { /* * The variable is valid. */ #if defined(VAR_RESOLVER_TRACE) fprintf(stderr, ".... cached var '%s' var %p flags = %.4x\n", - ObjStr(resVarInfo->nameObj), var, flags); + ObjStr(resVarInfo->nameObj), var, ((Var*)var)->flags); #endif return var; } @@ -5978,7 +5984,7 @@ framePtr->objc = objc; framePtr->objv = objv; framePtr->procPtr = procPtr; - framePtr->clientData = (ClientData)cscPtr; + framePtr->clientData = cscPtr; return ByteCompiled(interp, procPtr, TclGetString(objv[0])); } @@ -6325,7 +6331,7 @@ NsfTclStackFree(interp, pcPtr, "release parse context"); } #if defined(NRE) - result = ObjectDispatchFinalize(interp, cscPtr, result, "NRE", methodName); + result = ObjectDispatchFinalize(interp, cscPtr, result /*, "NRE" , methodName*/); #endif CscFinish(interp, cscPtr, "scripted finalize"); @@ -6596,7 +6602,7 @@ Tcl_Command cmd = cscPtr->cmdPtr; NsfObject *object = cscPtr->self; ClientData cp = Tcl_Command_objClientData(cmd); - register Tcl_ObjCmdProc *proc = Tcl_Command_objProc(cmd); + Tcl_ObjCmdProc *proc = Tcl_Command_objProc(cmd); int result; assert (object->teardown); @@ -6699,7 +6705,7 @@ result = MethodDispatch(object, interp, objc-1, objv+1, cmd, object, NULL, methodName, cscPtr->frameType|NSF_CSC_TYPE_ENSEMBLE, - cscPtr->flags|NSF_CSC_IMMEDIATE, 1); + cscPtr->flags|NSF_CSC_IMMEDIATE); goto obj_dispatch_ok; } } @@ -6803,7 +6809,7 @@ MethodDispatch(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Command cmd, NsfObject *object, NsfClass *cl, - CONST char *methodName, int frameType, int flags, int call) { + CONST char *methodName, int frameType, int flags) { NsfCallStackContent csc, *cscPtr; int result; @@ -6820,7 +6826,7 @@ * cp == NULL && !(Tcl_Command_flags(cmd) & NSF_CMD_NONLEAF_METHOD) * TODO: We could pass cmd==NULL, but is this worth it? */ - CscInit(cscPtr, object, cl, cmd, frameType, flags, "method dispatch"); + CscInit(cscPtr, object, cl, cmd, frameType, flags); result = MethodDispatchCsc(clientData, interp, objc, objv, cscPtr, methodName); @@ -6859,7 +6865,7 @@ // TODO: not all args needed NSF_INLINE static int ObjectDispatchFinalize(Tcl_Interp *interp, NsfCallStackContent *cscPtr, - int result, char *msg, CONST char *methodName) { + int result /*, char *msg, CONST char *methodName*/) { NsfRuntimeState *rst = RUNTIME_STATE(interp); NsfObject *object; int flags; @@ -6881,14 +6887,14 @@ * content structure is set to NULL. We are not able to check * parameter in such situations. */ - if (cscPtr->cmdPtr) { + if (result == TCL_OK && cscPtr->cmdPtr) { NsfParamDefs *paramDefs = ParamDefsGet(cscPtr->cmdPtr); - if (result == TCL_OK && paramDefs && paramDefs->returns) { + if (paramDefs && paramDefs->returns) { Tcl_Obj *valueObj = Tcl_GetObjResult(interp); result = ParameterCheck(interp, paramDefs->returns, valueObj, "return-value:", - RUNTIME_STATE(interp)->doCheckResults, + rst->doCheckResults, NULL); } } else { @@ -6960,13 +6966,12 @@ CONST char *methodName; NsfClass *cl = NULL; Tcl_Command cmd = NULL; - NsfRuntimeState *rst = RUNTIME_STATE(interp); Tcl_Obj *cmdName = object->cmdName, *methodObj, *cmdObj; NsfCallStackContent csc, *cscPtr = NULL; if (flags & NSF_CM_NO_SHIFT) { shift = 0; - cmdObj = object->cmdName; + cmdObj = cmdName; methodObj = objv[0]; } else { assert(objc>1); @@ -7019,22 +7024,23 @@ assert((flags & (NSF_CSC_MIXIN_STACK_PUSHED|NSF_CSC_FILTER_STACK_PUSHED)) == 0); - if (((objflags & NSF_FILTER_ORDER_DEFINED_AND_VALID) == NSF_FILTER_ORDER_DEFINED_AND_VALID) - && rst->doFilters - && !rst->guardCount) { - NsfCallStackContent *cscPtr1 = CallStackGetTopFrame(interp, NULL); + if (((objflags & NSF_FILTER_ORDER_DEFINED_AND_VALID) == NSF_FILTER_ORDER_DEFINED_AND_VALID)) { + NsfRuntimeState *rst = RUNTIME_STATE(interp); + if (rst->doFilters && !rst->guardCount) { + NsfCallStackContent *cscPtr1 = CallStackGetTopFrame(interp, NULL); + + if (!cscPtr1 || + (object != cscPtr1->self || (cscPtr1->frameType != NSF_CSC_TYPE_ACTIVE_FILTER))) { - if (!cscPtr1 || - (object != cscPtr1->self || (cscPtr1->frameType != NSF_CSC_TYPE_ACTIVE_FILTER))) { + FilterStackPush(interp, object, methodObj); + flags |= NSF_CSC_FILTER_STACK_PUSHED; - FilterStackPush(interp, object, methodObj); - flags |= NSF_CSC_FILTER_STACK_PUSHED; - - cmd = FilterSearchProc(interp, object, &object->filterStack->currentCmdPtr, &cl); - if (cmd) { - /*fprintf(stderr, "filterSearchProc returned cmd %p\n", cmd);*/ - frameType = NSF_CSC_TYPE_ACTIVE_FILTER; - methodName = (char *)Tcl_GetCommandName(interp, cmd); + cmd = FilterSearchProc(interp, object, &object->filterStack->currentCmdPtr, &cl); + if (cmd) { + /*fprintf(stderr, "filterSearchProc returned cmd %p\n", cmd);*/ + frameType = NSF_CSC_TYPE_ACTIVE_FILTER; + methodName = (char *)Tcl_GetCommandName(interp, cmd); + } } } } @@ -7067,7 +7073,7 @@ /*fprintf(stderr, "mixinsearch returned an error for %p %s.%s\n", object, objectName(object),methodName);*/ cscPtr = CscAlloc(interp, &csc, NULL); - CscInit(cscPtr, object, cl, NULL, frameType, flags, "mixinsearch failed"); + CscInit(cscPtr, object, cl, NULL, frameType, flags); goto exit_object_dispatch; } if (cmd) { @@ -7139,7 +7145,7 @@ * We found the method to dispatch. */ cscPtr = CscAlloc(interp, &csc, cmd); - CscInit(cscPtr, object, cl, cmd, frameType, flags, "object dispatch"); + CscInit(cscPtr, object, cl, cmd, frameType, flags); if ((cscPtr->frameType == NSF_CSC_TYPE_ACTIVE_FILTER)) { /* run filters not NRE enabled */ @@ -7164,7 +7170,7 @@ * The method to be dispatched is unknown */ cscPtr = CscAlloc(interp, &csc, cmd); - CscInit(cscPtr, object, cl, cmd, frameType, flags, "unknown"); + CscInit(cscPtr, object, cl, cmd, frameType, flags); flags |= NSF_CSC_UNKNOWN; cscPtr->flags |= NSF_CSC_UNKNOWN; @@ -7179,7 +7185,7 @@ assert(cscPtr); if (!(cscPtr->flags & NSF_CSC_CALL_IS_NRE)) { - result = ObjectDispatchFinalize(interp, cscPtr, result, "immediate", methodName); + result = ObjectDispatchFinalize(interp, cscPtr, result /*, "immediate" , methodName*/); CscListRemove(interp, cscPtr); CscFinish(interp, cscPtr, "non-scripted finalize"); } @@ -7274,11 +7280,7 @@ } else { result = CallMethod(object, interp, methodObj, 2, 0, NSF_CSC_IMMEDIATE|flags); } - // REMOVE ME if (result != TCL_OK) { - fprintf(stderr, "destroy of %p returned %d\n", object, result); - } - if (result != TCL_OK) { /* * The object might be already gone here, since we have no stack frame. * Therefore, we can't even use nsf::current object safely. @@ -8888,15 +8890,15 @@ Tcl_NRAddCallback(interp, NextInvokeFinalize, freeArgumentVector ? (ClientData)objv : NULL, cscPtr, NULL, NULL); return MethodDispatch((ClientData)object, interp, objc, objv, cmd, - object, cl, methodName, frameType, flags, 3); + object, cl, methodName, frameType, flags); } else { result = MethodDispatch((ClientData)object, interp, objc, objv, cmd, - object, cl, methodName, frameType, flags, 3); + object, cl, methodName, frameType, flags); } } #else result = MethodDispatch((ClientData)object, interp, objc, objv, cmd, - object, cl, methodName, frameType, 0, 3); + object, cl, methodName, frameType, 0); #endif } else if (result == TCL_OK) { /* @@ -10851,7 +10853,7 @@ (char *) NULL); } return MethodDispatch((ClientData)self, interp, objc, objv, tcd->aliasedCmd, self, tcd->class, - methodName, 0, 0, 4); + methodName, 0, 0); } static int @@ -11234,7 +11236,7 @@ INCR_REF_COUNT(newValue); mustDecrNewValue = 1; pcPtr->flags[i] |= NSF_PC_MUST_DECR; - pcPtr->mustDecr = 1; + pcPtr->status |= NSF_PC_STATUS_MUST_DECR; } else { mustDecrNewValue = 0; } @@ -11271,7 +11273,7 @@ */ if (mustDecrList) { pcPtr->flags[i] |= NSF_PC_MUST_DECR; - pcPtr->mustDecr = 1; + pcPtr->status |= NSF_PC_STATUS_MUST_DECR; } } } @@ -11360,8 +11362,9 @@ return TCL_ERROR; } - if (pcPtr->flags[j] & NSF_PC_MUST_DECR) - pcPtr->mustDecr = 1; + if (pcPtr->flags[j] & NSF_PC_MUST_DECR) { + pcPtr->status |= NSF_PC_STATUS_MUST_DECR; + } } else { Tcl_ResetResult(interp); @@ -11420,9 +11423,9 @@ &pcPtr->flags[i], &pcPtr->clientData[i], &pcPtr->objv[i]) != TCL_OK) { return TCL_ERROR; } - if (pcPtr->flags[i] & NSF_PC_MUST_DECR) - pcPtr->mustDecr = 1; - + if (pcPtr->flags[i] & NSF_PC_MUST_DECR) { + pcPtr->status |= NSF_PC_STATUS_MUST_DECR; + } /* * objv is always passed via pcPtr->objv */ @@ -12426,10 +12429,6 @@ } for (; unstackedEntries; unstackedEntries = unstackedEntries->nextPtr) { NsfCallStackContent *cscPtr = (NsfCallStackContent *)unstackedEntries->cl; - //fprintf(stderr, "unstackedEntry cscPtr %p\n", cscPtr); - //fprintf(stderr, "unstackedEntry object %s class %s\n", - //objectName(cscPtr->self), - // className(cscPtr->cl)); if (cscPtr && cscPtr->self == object) count ++; if (cscPtr && (NsfObject*)cscPtr->cl == object) count ++; } @@ -12930,7 +12929,7 @@ nobjc+1, nobjv-1, cmd, object, NULL /*NsfClass *cl*/, Tcl_GetCommandName(interp,cmd), - NSF_CSC_TYPE_PLAIN, flags, 5); + NSF_CSC_TYPE_PLAIN, flags); if (withFrame == FrameObjectIdx) { Nsf_PopFrameObj(interp, framePtr); } @@ -13425,7 +13424,7 @@ (char *) NULL); } result = MethodDispatch((ClientData)self, interp, nobjc+2, nobjv, cmd, self, cl, - methodName, 0, 0, 6); + methodName, 0, 0); } else { #if 0 /* TODO attempt to make "my" NRE-enabled, failed so far (crash in mixinInheritanceTest) */ @@ -14676,7 +14675,7 @@ Tcl_Interp_varFramePtr(interp) = varFramePtr->callerPtr; cscPtr->flags = 0; - CscInit(cscPtr, object, NULL /*cl*/, NULL/*cmd*/, NSF_CSC_TYPE_PLAIN, 0, "initcmd"); + CscInit(cscPtr, object, NULL /*cl*/, NULL/*cmd*/, NSF_CSC_TYPE_PLAIN, 0); Nsf_PushFrameCsc(interp, cscPtr, framePtr2); if (paramPtr->flags & NSF_ARG_INITCMD) { Index: generic/nsfInt.h =================================================================== diff -u -r8651e9f7d6d526196cfe4dad14d08b857a66f5d8 -r937992852d688bc487c8f59273dfa045d077a9c8 --- generic/nsfInt.h (.../nsfInt.h) (revision 8651e9f7d6d526196cfe4dad14d08b857a66f5d8) +++ generic/nsfInt.h (.../nsfInt.h) (revision 937992852d688bc487c8f59273dfa045d077a9c8) @@ -390,14 +390,18 @@ /* flags for ParseContext */ #define NSF_PC_MUST_DECR 0x0001 +#define NSF_PC_STATUS_MUST_DECR 0x0001 +#define NSF_PC_STATUS_FREE_OBJV 0x0002 +#define NSF_PC_STATUS_FREE_CD 0x0004 + #define NsfObjectSetClass(obj) \ (obj)->flags |= NSF_IS_CLASS #define NsfObjectClearClass(obj) \ (obj)->flags &= ~NSF_IS_CLASS #define NsfObjectIsClass(obj) \ ((obj)->flags & NSF_IS_CLASS) #define NsfObjectToClass(obj) \ - (NsfClass*)((((NsfObject*)obj)->flags & NSF_IS_CLASS)?obj:0) + (NsfClass*)((((NsfObject*)obj)->flags & NSF_IS_CLASS)?obj:NULL) /* @@ -637,11 +641,11 @@ #define NSF_CSC_IMMEDIATE 0x0020 #define NSF_CSC_FORCE_FRAME 0x0040 #define NSF_CSC_CALL_IS_NRE 0x0100 -#define NSF_CSC_MIXIN_STACK_PUSHED 0x0200 -#define NSF_CSC_FILTER_STACK_PUSHED 0x0400 -#define NSF_CSC_UNKNOWN 0x0800 -#define NSF_CSC_CALL_IS_TRANSPARENT 0x1000 -#define NSF_CSC_OBJECT_ACTIVATED 0x2000 +#define NSF_CSC_MIXIN_STACK_PUSHED 0x0400 +#define NSF_CSC_FILTER_STACK_PUSHED 0x0800 +#define NSF_CSC_UNKNOWN 0x1000 +#define NSF_CSC_CALL_IS_TRANSPARENT 0x2000 +#define NSF_CSC_OBJECT_ACTIVATED 0x4000 #define NSF_CSC_COPY_FLAGS (NSF_CSC_MIXIN_STACK_PUSHED|NSF_CSC_FILTER_STACK_PUSHED|NSF_CSC_IMMEDIATE|NSF_CSC_CALL_IS_TRANSPARENT|NSF_CSC_FORCE_FRAME) /* flags for call method */ Index: generic/nsfStack.c =================================================================== diff -u -r60604f6962105d881e376602217c2719caa1167d -r937992852d688bc487c8f59273dfa045d077a9c8 --- generic/nsfStack.c (.../nsfStack.c) (revision 60604f6962105d881e376602217c2719caa1167d) +++ generic/nsfStack.c (.../nsfStack.c) (revision 937992852d688bc487c8f59273dfa045d077a9c8) @@ -827,7 +827,7 @@ */ NSF_INLINE static void CscInit(/*@notnull@*/ NsfCallStackContent *cscPtr, NsfObject *object, NsfClass *cl, - Tcl_Command cmd, int frameType, int flags, char *msg) { + Tcl_Command cmd, unsigned short frameType, unsigned short flags) { assert(cscPtr); @@ -884,10 +884,11 @@ cscPtr->self = object; cscPtr->cl = cl; cscPtr->cmdPtr = cmd; - cscPtr->frameType = frameType; - cscPtr->filterStackEntry = (frameType == NSF_CSC_TYPE_ACTIVE_FILTER) ? object->filterStack : NULL; cscPtr->objv = NULL; + cscPtr->filterStackEntry = object->filterStack; + cscPtr->frameType = frameType; + /*fprintf(stderr, "CscInit %p (%s) object %p %s flags %.6x cmdPtr %p\n",cscPtr, msg, object, objectName(object), cscPtr->flags, cscPtr->cmdPtr);*/ } @@ -974,11 +975,13 @@ object->flags & NSF_DESTROY_CALLED, object->flags & NSF_DESTROY_CALLED_SUCCESS);*/ +#if 0 // TODO remove block if (((object->flags & NSF_DESTROY_CALLED_SUCCESS)>0) != ((object->flags & NSF_DESTROY_CALLED)>0)) { fprintf(stderr, "*** flags differ for class %p\n", object); } +#endif if (object->activationCount < 1 && object->flags & NSF_DESTROY_CALLED_SUCCESS && allowDestroy) { CallStackDoDestroy(interp, object); } Index: generic/tclAPI.h =================================================================== diff -u -r6c2e8f94be1ba335ff90d4b6b5132c98a9f5c242 -r937992852d688bc487c8f59273dfa045d077a9c8 --- generic/tclAPI.h (.../tclAPI.h) (revision 6c2e8f94be1ba335ff90d4b6b5132c98a9f5c242) +++ generic/tclAPI.h (.../tclAPI.h) (revision 937992852d688bc487c8f59273dfa045d077a9c8) @@ -455,7 +455,7 @@ } else { Tcl_Obj *name = (Tcl_Obj *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfCAllocMethod(interp, cl, name); } @@ -474,7 +474,7 @@ } else { CONST char *name = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfCCreateMethod(interp, cl, name, objc, objv); } @@ -493,7 +493,7 @@ } else { Tcl_Obj *object = (Tcl_Obj *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfCDeallocMethod(interp, cl, object); } @@ -513,7 +513,7 @@ CONST char *filter = (CONST char *)pc.clientData[0]; Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfCFilterGuardMethod(interp, cl, filter, guard); } @@ -533,7 +533,7 @@ CONST char *mixin = (CONST char *)pc.clientData[0]; Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfCMixinGuardMethod(interp, cl, mixin, guard); } @@ -552,7 +552,7 @@ } else { NsfObject *withChildof = (NsfObject *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfCNewMethod(interp, cl, withChildof, objc-pc.lastobjc, objv+pc.lastobjc); } @@ -571,7 +571,7 @@ } else { Tcl_Obj *name = (Tcl_Obj *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfCRecreateMethod(interp, cl, name, objc, objv); } @@ -590,7 +590,7 @@ } else { CONST char *filter = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfClassInfoFilterguardMethod(interp, cl, filter); } @@ -610,7 +610,7 @@ int withGuards = (int )PTR2INT(pc.clientData[0]); CONST char *pattern = (CONST char *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfClassInfoFiltermethodsMethod(interp, cl, withGuards, pattern); } @@ -630,7 +630,7 @@ int withDefinition = (int )PTR2INT(pc.clientData[0]); CONST char *name = (CONST char *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfClassInfoForwardMethod(interp, cl, withDefinition, name); } @@ -649,7 +649,7 @@ } else { CONST char *pattern = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfClassInfoHeritageMethod(interp, cl, pattern); } @@ -679,7 +679,7 @@ return TCL_OK; } - ParseContextRelease(&pc); + assert(pc.status == 0); returnCode = NsfClassInfoInstancesMethod(interp, cl, withClosure, patternString, patternObj); if (pattern) { @@ -703,7 +703,7 @@ int infomethodsubcmd = (int )PTR2INT(pc.clientData[0]); Tcl_Obj *name = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfClassInfoMethodMethod(interp, cl, infomethodsubcmd, name); } @@ -727,7 +727,7 @@ int withPath = (int )PTR2INT(pc.clientData[4]); CONST char *pattern = (CONST char *)pc.clientData[5]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfClassInfoMethodsMethod(interp, cl, withCallprotection, withIncontext, withMethodtype, withNomixins, withPath, pattern); } @@ -758,7 +758,7 @@ return TCL_OK; } - ParseContextRelease(&pc); + assert(pc.status == 0); returnCode = NsfClassInfoMixinOfMethod(interp, cl, withClosure, withScope, patternString, patternObj); if (pattern) { @@ -793,7 +793,7 @@ return TCL_OK; } - ParseContextRelease(&pc); + assert(pc.status == 0); returnCode = NsfClassInfoMixinclassesMethod(interp, cl, withClosure, withGuards, patternString, patternObj); if (pattern) { @@ -816,7 +816,7 @@ } else { CONST char *mixin = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfClassInfoMixinguardMethod(interp, cl, mixin); } @@ -846,7 +846,7 @@ return TCL_OK; } - ParseContextRelease(&pc); + assert(pc.status == 0); returnCode = NsfClassInfoSubclassMethod(interp, cl, withClosure, patternString, patternObj); if (pattern) { @@ -870,7 +870,7 @@ int withClosure = (int )PTR2INT(pc.clientData[0]); Tcl_Obj *pattern = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfClassInfoSuperclassMethod(interp, cl, withClosure, pattern); } @@ -892,7 +892,7 @@ int withFrame = (int )PTR2INT(pc.clientData[3]); Tcl_Obj *cmdName = (Tcl_Obj *)pc.clientData[4]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfAliasCmd(interp, object, withPer_object, methodName, withFrame, cmdName); } @@ -912,7 +912,7 @@ int assertionsubcmd = (int )PTR2INT(pc.clientData[1]); Tcl_Obj *arg = (Tcl_Obj *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfAssertionCmd(interp, object, assertionsubcmd, arg); } @@ -940,7 +940,7 @@ int configureoption = (int )PTR2INT(pc.clientData[0]); Tcl_Obj *value = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfConfigureCmd(interp, configureoption, value); } @@ -960,7 +960,7 @@ Tcl_Obj *rootMetaClass = (Tcl_Obj *)pc.clientData[1]; Tcl_Obj *systemMethods = (Tcl_Obj *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfCreateObjectSystemCmd(interp, rootClass, rootMetaClass, systemMethods); } @@ -978,7 +978,7 @@ } else { int currentoption = (int )PTR2INT(pc.clientData[0]); - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfCurrentCmd(interp, currentoption); } @@ -996,7 +996,7 @@ } else { - ParseContextRelease(&pc); + return NsfDebugRunAssertionsCmd(interp); } @@ -1016,7 +1016,7 @@ CONST char *oldCmd = (CONST char *)pc.clientData[1]; CONST char *newCmd = (CONST char *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfDeprecatedCmd(interp, what, oldCmd, newCmd); } @@ -1036,7 +1036,7 @@ int withFrame = (int )PTR2INT(pc.clientData[1]); Tcl_Obj *command = (Tcl_Obj *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfDispatchCmd(interp, object, withFrame, command, objc-pc.lastobjc, objv+pc.lastobjc); } @@ -1055,7 +1055,7 @@ NsfObject *object = (NsfObject *)pc.clientData[0]; CONST char *varname = (CONST char *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfExistsVarCmd(interp, object, varname); } @@ -1073,7 +1073,7 @@ } else { - ParseContextRelease(&pc); + return NsfFinalizeObjCmd(interp); } @@ -1100,7 +1100,7 @@ int withVerbose = (int )PTR2INT(pc.clientData[8]); Tcl_Obj *target = (Tcl_Obj *)pc.clientData[9]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfForwardCmd(interp, object, withPer_object, method, withDefault, withEarlybinding, withMethodprefix, withObjscope, withOnerror, withVerbose, target, objc-pc.lastobjc, objv+pc.lastobjc); } @@ -1118,7 +1118,7 @@ } else { NsfObject *object = (NsfObject *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfImportvarCmd(interp, object, objc-pc.lastobjc, objv+pc.lastobjc); } @@ -1136,7 +1136,7 @@ } else { CONST char *name = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfInterpObjCmd(interp, name, objc, objv); } @@ -1154,7 +1154,7 @@ } else { NsfClass *class = (NsfClass *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfInvalidateObjectParameterCmd(interp, class); } @@ -1174,7 +1174,7 @@ Tcl_Obj *constraint = (Tcl_Obj *)pc.clientData[1]; Tcl_Obj *value = (Tcl_Obj *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfIsCmd(interp, withComplain, constraint, value); } @@ -1192,7 +1192,7 @@ } else { Tcl_Obj *object = (Tcl_Obj *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfIsObjectCmd(interp, object); } @@ -1218,7 +1218,7 @@ Tcl_Obj *withPrecondition = (Tcl_Obj *)pc.clientData[7]; Tcl_Obj *withPostcondition = (Tcl_Obj *)pc.clientData[8]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfMethodCmd(interp, object, withInner_namespace, withPer_object, withPublic, name, args, body, withPrecondition, withPostcondition); } @@ -1240,7 +1240,7 @@ int methodproperty = (int )PTR2INT(pc.clientData[3]); Tcl_Obj *value = (Tcl_Obj *)pc.clientData[4]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfMethodPropertyCmd(interp, object, withPer_object, methodName, methodproperty, value); } @@ -1259,7 +1259,7 @@ int withLocal = (int )PTR2INT(pc.clientData[0]); Tcl_Obj *method = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfMyCmd(interp, withLocal, method, objc-pc.lastobjc, objv+pc.lastobjc); } @@ -1278,7 +1278,7 @@ Tcl_Obj *fromNs = (Tcl_Obj *)pc.clientData[0]; Tcl_Obj *toNs = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfNSCopyCmdsCmd(interp, fromNs, toNs); } @@ -1297,7 +1297,7 @@ Tcl_Obj *fromNs = (Tcl_Obj *)pc.clientData[0]; Tcl_Obj *toNs = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfNSCopyVarsCmd(interp, fromNs, toNs); } @@ -1315,7 +1315,7 @@ } else { Tcl_Obj *arguments = (Tcl_Obj *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfNextCmd(interp, arguments); } @@ -1333,7 +1333,7 @@ } else { Tcl_Obj *objectname = (Tcl_Obj *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfQualifyObjCmd(interp, objectname); } @@ -1353,7 +1353,7 @@ int relationtype = (int )PTR2INT(pc.clientData[1]); Tcl_Obj *value = (Tcl_Obj *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfRelationCmd(interp, object, relationtype, value); } @@ -1371,7 +1371,7 @@ } else { - ParseContextRelease(&pc); + return NsfSelfCmd(interp); } @@ -1391,7 +1391,7 @@ Tcl_Obj *varname = (Tcl_Obj *)pc.clientData[1]; Tcl_Obj *value = (Tcl_Obj *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfSetVarCmd(interp, object, varname, value); } @@ -1411,7 +1411,7 @@ int withPer_object = (int )PTR2INT(pc.clientData[1]); Tcl_Obj *parameter = (Tcl_Obj *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfSetterCmd(interp, object, withPer_object, parameter); } @@ -1429,7 +1429,7 @@ } else { - ParseContextRelease(&pc); + return NsfShowStackCmd(interp); } @@ -1450,7 +1450,7 @@ int withReset = (int )PTR2INT(pc.clientData[1]); Tcl_Obj *name = (Tcl_Obj *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfOAutonameMethod(interp, obj, withInstance, withReset, name); } @@ -1469,7 +1469,7 @@ } else { - ParseContextRelease(&pc); + return NsfOCleanupMethod(interp, obj); } @@ -1498,7 +1498,7 @@ } else { - ParseContextRelease(&pc); + return NsfODestroyMethod(interp, obj); } @@ -1517,7 +1517,7 @@ } else { CONST char *varname = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfOExistsMethod(interp, obj, varname); } @@ -1537,7 +1537,7 @@ CONST char *filter = (CONST char *)pc.clientData[0]; Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfOFilterGuardMethod(interp, obj, filter, guard); } @@ -1567,7 +1567,7 @@ CONST char *mixin = (CONST char *)pc.clientData[0]; Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfOMixinGuardMethod(interp, obj, mixin, guard); } @@ -1586,7 +1586,7 @@ } else { - ParseContextRelease(&pc); + return NsfONoinitMethod(interp, obj); } @@ -1605,7 +1605,7 @@ } else { - ParseContextRelease(&pc); + return NsfORequireNamespaceMethod(interp, obj); } @@ -1654,7 +1654,7 @@ } else { - ParseContextRelease(&pc); + return NsfOVolatileMethod(interp, obj); } @@ -1673,7 +1673,7 @@ } else { CONST char *varname = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfOVwaitMethod(interp, obj, varname); } @@ -1693,7 +1693,7 @@ NsfClass *withType = (NsfClass *)pc.clientData[0]; CONST char *pattern = (CONST char *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoChildrenMethod(interp, obj, withType, pattern); } @@ -1712,7 +1712,7 @@ } else { - ParseContextRelease(&pc); + return NsfObjInfoClassMethod(interp, obj); } @@ -1731,7 +1731,7 @@ } else { CONST char *name = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoFilterguardMethod(interp, obj, name); } @@ -1752,7 +1752,7 @@ int withOrder = (int )PTR2INT(pc.clientData[1]); CONST char *pattern = (CONST char *)pc.clientData[2]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoFiltermethodsMethod(interp, obj, withGuards, withOrder, pattern); } @@ -1772,7 +1772,7 @@ int withDefinition = (int )PTR2INT(pc.clientData[0]); CONST char *name = (CONST char *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoForwardMethod(interp, obj, withDefinition, name); } @@ -1791,7 +1791,7 @@ } else { NsfClass *class = (NsfClass *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoHasMixinMethod(interp, obj, class); } @@ -1810,7 +1810,7 @@ } else { NsfClass *class = (NsfClass *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoHasTypeMethod(interp, obj, class); } @@ -1829,7 +1829,7 @@ } else { - ParseContextRelease(&pc); + return NsfObjInfoHasnamespaceMethod(interp, obj); } @@ -1848,7 +1848,7 @@ } else { int objectkind = (int )PTR2INT(pc.clientData[0]); - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoIsMethod(interp, obj, objectkind); } @@ -1867,7 +1867,7 @@ } else { CONST char *filter = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoLookupFilterMethod(interp, obj, filter); } @@ -1886,7 +1886,7 @@ } else { Tcl_Obj *name = (Tcl_Obj *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoLookupMethodMethod(interp, obj, name); } @@ -1911,7 +1911,7 @@ int withSource = (int )PTR2INT(pc.clientData[5]); CONST char *pattern = (CONST char *)pc.clientData[6]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoLookupMethodsMethod(interp, obj, withCallprotection, withIncontext, withMethodtype, withNomixins, withPath, withSource, pattern); } @@ -1930,7 +1930,7 @@ } else { NsfClass *withType = (NsfClass *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoLookupSlotsMethod(interp, obj, withType); } @@ -1950,7 +1950,7 @@ int infomethodsubcmd = (int )PTR2INT(pc.clientData[0]); Tcl_Obj *name = (Tcl_Obj *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoMethodMethod(interp, obj, infomethodsubcmd, name); } @@ -1974,7 +1974,7 @@ int withPath = (int )PTR2INT(pc.clientData[4]); CONST char *pattern = (CONST char *)pc.clientData[5]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoMethodsMethod(interp, obj, withCallprotection, withIncontext, withMethodtype, withNomixins, withPath, pattern); } @@ -2005,7 +2005,7 @@ return TCL_OK; } - ParseContextRelease(&pc); + assert(pc.status == 0); returnCode = NsfObjInfoMixinclassesMethod(interp, obj, withGuards, withOrder, patternString, patternObj); if (pattern) { @@ -2028,7 +2028,7 @@ } else { CONST char *mixin = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoMixinguardMethod(interp, obj, mixin); } @@ -2047,7 +2047,7 @@ } else { - ParseContextRelease(&pc); + return NsfObjInfoParentMethod(interp, obj); } @@ -2067,7 +2067,7 @@ int withIntrinsic = (int )PTR2INT(pc.clientData[0]); CONST char *pattern = (CONST char *)pc.clientData[1]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoPrecedenceMethod(interp, obj, withIntrinsic, pattern); } @@ -2086,7 +2086,7 @@ } else { CONST char *pattern = (CONST char *)pc.clientData[0]; - ParseContextRelease(&pc); + assert(pc.status == 0); return NsfObjInfoVarsMethod(interp, obj, pattern); }