From 4536322b256c1539a134ea7ecc4a7c32e7b05451 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 Aug 2013 19:45:13 +0000 Subject: Give (objc, objv) their own ride from enter to leave traces. --- generic/tclBasic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 7110025..067da63 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -4727,7 +4727,7 @@ TEOV_RunEnterTraces( */ TclNRAddCallback(interp, TEOV_RunLeaveTraces, INT2PTR(traceCode), - commandPtr, cmdPtr, NULL); + commandPtr, cmdPtr, Tcl_NewListObj(objc, objv)); cmdPtr->refCount++; } else { Tcl_DecrRefCount(commandPtr); @@ -4748,11 +4748,10 @@ TEOV_RunLeaveTraces( int traceCode = PTR2INT(data[0]); Tcl_Obj *commandPtr = data[1]; Command *cmdPtr = data[2]; + Tcl_Obj *wordsPtr = data[3]; command = Tcl_GetStringFromObj(commandPtr, &length); - if (TCL_OK != Tcl_ListObjGetElements(interp, commandPtr, &objc, &objv)) { - Tcl_Panic("Who messed with commandPtr?"); - } + Tcl_ListObjGetElements(NULL, wordsPtr, &objc, &objv); if (!(cmdPtr->flags & CMD_IS_DELETED)) { if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) && traceCode == TCL_OK){ @@ -4765,6 +4764,7 @@ TEOV_RunLeaveTraces( } } Tcl_DecrRefCount(commandPtr); + Tcl_DecrRefCount(wordsPtr); /* * As cmdPtr is set, TclNRRunCallbacks is about to reduce the numlevels. -- cgit v0.12 From dddbd100aedbc995c1a203715479978f79e82ba6 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 Aug 2013 20:27:30 +0000 Subject: Revise GetCommandSource() to return a normal Tcl_Obj value. --- generic/tclBasic.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 067da63..6542726 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -3358,15 +3358,6 @@ CancelEvalProc( * This function returns a Tcl_Obj with the full source string for the * command. This insures that traces get a correct NUL-terminated command * string. The Tcl_Obj has refCount==1. - * - * *** MAINTAINER WARNING *** - * The returned Tcl_Obj is all wrong for any purpose but getting the - * source string for an objc/objv command line in the stringRep (no - * stringRep if no source is available) and the corresponding substituted - * version in the List intrep. - * This means that the intRep and stringRep DO NOT COINCIDE! Using these - * Tcl_Objs normally is likely to break things. - * *---------------------------------------------------------------------- */ @@ -3376,13 +3367,13 @@ GetCommandSource( int objc, Tcl_Obj *const objv[]) { - Tcl_Obj *objPtr, *obj2Ptr; + Tcl_Obj *objPtr = NULL; CmdFrame *cfPtr = iPtr->cmdFramePtr; - const char *command = NULL; - int numChars; - objPtr = Tcl_NewListObj(objc, objv); if (cfPtr && (cfPtr->numLevels == iPtr->numLevels-1)) { + const char *command = NULL; + int numChars; + switch (cfPtr->type) { case TCL_LOCATION_EVAL: case TCL_LOCATION_SOURCE: @@ -3395,13 +3386,12 @@ GetCommandSource( break; } if (command) { - obj2Ptr = Tcl_NewStringObj(command, numChars); - objPtr->bytes = obj2Ptr->bytes; - objPtr->length = numChars; - obj2Ptr->bytes = NULL; - Tcl_DecrRefCount(obj2Ptr); + objPtr = Tcl_NewStringObj(command, numChars); } } + if (objPtr == NULL) { + objPtr = Tcl_NewListObj(objc, objv); + } Tcl_IncrRefCount(objPtr); return objPtr; } -- cgit v0.12 From fec32bb50c597bfbb21ad55211339355034f6d55 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 Aug 2013 16:48:30 +0000 Subject: Revised GetCommandSource() can (and thus should) return a normal zero refcount value. --- generic/tclBasic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 6542726..9755a21 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -3357,7 +3357,7 @@ CancelEvalProc( * * This function returns a Tcl_Obj with the full source string for the * command. This insures that traces get a correct NUL-terminated command - * string. The Tcl_Obj has refCount==1. + * string. *---------------------------------------------------------------------- */ @@ -3392,7 +3392,6 @@ GetCommandSource( if (objPtr == NULL) { objPtr = Tcl_NewListObj(objc, objv); } - Tcl_IncrRefCount(objPtr); return objPtr; } -- cgit v0.12 From de857ca207e4dceea586bf2dbfe497df4d9d02c8 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 10 Aug 2013 05:16:38 +0000 Subject: Arrange for both execution traces and [info frame] to get their pre-subst source strings from a common routine, with care taken to reduce copying by that routine. --- generic/tclBasic.c | 41 +++++++++++++++-------------------------- generic/tclCmdIL.c | 25 ++++++++++++++++++++++--- generic/tclExecute.c | 19 +++++++++++++++++-- generic/tclInt.h | 5 +++++ 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 9755a21..1cd2eae 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -3367,32 +3367,12 @@ GetCommandSource( int objc, Tcl_Obj *const objv[]) { - Tcl_Obj *objPtr = NULL; CmdFrame *cfPtr = iPtr->cmdFramePtr; - if (cfPtr && (cfPtr->numLevels == iPtr->numLevels-1)) { - const char *command = NULL; - int numChars; - - switch (cfPtr->type) { - case TCL_LOCATION_EVAL: - case TCL_LOCATION_SOURCE: - command = cfPtr->cmd; - numChars = cfPtr->len; - break; - case TCL_LOCATION_BC: - case TCL_LOCATION_PREBC: - command = TclGetSrcInfoForCmd(iPtr, &numChars); - break; - } - if (command) { - objPtr = Tcl_NewStringObj(command, numChars); - } + if (cfPtr && (cfPtr->numLevels != iPtr->numLevels-1)) { + cfPtr = NULL; } - if (objPtr == NULL) { - objPtr = Tcl_NewListObj(objc, objv); - } - return objPtr; + return TclGetSourceFromFrame(cfPtr, objc, objv); } /* @@ -4678,6 +4658,7 @@ TEOV_RunEnterTraces( Tcl_Obj *commandPtr; commandPtr = GetCommandSource(iPtr, objc, objv); + Tcl_IncrRefCount(commandPtr); command = Tcl_GetStringFromObj(commandPtr, &length); /* @@ -5013,6 +4994,7 @@ TclEvalEx( eeFramePtr->nextPtr = iPtr->cmdFramePtr; eeFramePtr->nline = 0; eeFramePtr->line = NULL; + eeFramePtr->cmdObj = NULL; iPtr->cmdFramePtr = eeFramePtr; if (iPtr->evalFlags & TCL_EVAL_FILE) { @@ -5243,6 +5225,10 @@ TclEvalEx( eeFramePtr->line = NULL; eeFramePtr->nline = 0; + if (eeFramePtr->cmdObj) { + Tcl_DecrRefCount(eeFramePtr->cmdObj); + eeFramePtr->cmdObj = NULL; + } if (code != TCL_OK) { goto error; @@ -5983,7 +5969,6 @@ TclNREvalObjEx( Tcl_IncrRefCount(objPtr); listPtr = TclListObjCopy(interp, objPtr); Tcl_IncrRefCount(listPtr); - TclDecrRefCount(objPtr); if (word != INT_MIN) { /* @@ -6013,7 +5998,9 @@ TclNREvalObjEx( eoFramePtr->framePtr = iPtr->framePtr; eoFramePtr->nextPtr = iPtr->cmdFramePtr; - eoFramePtr->cmd = Tcl_GetStringFromObj(listPtr, &(eoFramePtr->len)); + eoFramePtr->cmdObj = objPtr; + eoFramePtr->cmd = NULL; + eoFramePtr->len = 0; eoFramePtr->data.eval.path = NULL; iPtr->cmdFramePtr = eoFramePtr; @@ -6021,7 +6008,7 @@ TclNREvalObjEx( TclMarkTailcall(interp); TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr, - NULL, NULL); + objPtr, NULL); ListObjGetElements(listPtr, objc, objv); return TclNREvalObjv(interp, objc, objv, flags, NULL); @@ -6156,6 +6143,7 @@ TEOEx_ListCallback( Interp *iPtr = (Interp *) interp; Tcl_Obj *listPtr = data[0]; CmdFrame *eoFramePtr = data[1]; + Tcl_Obj *objPtr = data[2]; /* * Remove the cmdFrame @@ -6165,6 +6153,7 @@ TEOEx_ListCallback( iPtr->cmdFramePtr = eoFramePtr->nextPtr; TclStackFree(interp, eoFramePtr); } + TclDecrRefCount(objPtr); TclDecrRefCount(listPtr); return result; diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 180d814..da9edd6 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -1266,6 +1266,25 @@ InfoFrameCmd( */ Tcl_Obj * +TclGetSourceFromFrame( + CmdFrame *cfPtr, + int objc, + Tcl_Obj *const objv[]) +{ + if (cfPtr == NULL) { + return Tcl_NewListObj(objc, objv); + } + if (cfPtr->cmdObj == NULL) { + if (cfPtr->cmd == NULL) { + cfPtr->cmd = TclGetSrcInfoForCmdFrame(cfPtr, &cfPtr->len); + } + cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len); + Tcl_IncrRefCount(cfPtr->cmdObj); + } + return cfPtr->cmdObj; +} + +Tcl_Obj * TclInfoFrame( Tcl_Interp *interp, /* Current interpreter. */ CmdFrame *framePtr) /* Frame to get info for. */ @@ -1307,7 +1326,7 @@ TclInfoFrame( } else { ADD_PAIR("line", Tcl_NewIntObj(1)); } - ADD_PAIR("cmd", Tcl_NewStringObj(framePtr->cmd, framePtr->len)); + ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL)); break; case TCL_LOCATION_PREBC: @@ -1355,7 +1374,7 @@ TclInfoFrame( Tcl_DecrRefCount(fPtr->data.eval.path); } - ADD_PAIR("cmd", Tcl_NewStringObj(fPtr->cmd, fPtr->len)); + ADD_PAIR("cmd", TclGetSourceFromFrame(fPtr, 0, NULL)); TclStackFree(interp, fPtr); break; } @@ -1374,7 +1393,7 @@ TclInfoFrame( * the result list object. */ - ADD_PAIR("cmd", Tcl_NewStringObj(framePtr->cmd, framePtr->len)); + ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL)); break; case TCL_LOCATION_PROC: diff --git a/generic/tclExecute.c b/generic/tclExecute.c index f6072a1..d8ccf40 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -2006,6 +2006,7 @@ TclNRExecuteByteCode( bcFramePtr->litarg = NULL; bcFramePtr->data.tebc.codePtr = codePtr; bcFramePtr->data.tebc.pc = NULL; + bcFramePtr->cmdObj = NULL; bcFramePtr->cmd = NULL; bcFramePtr->len = 0; @@ -2130,6 +2131,11 @@ TEBCresume( result = TCL_ERROR; } NRE_ASSERT(iPtr->cmdFramePtr == bcFramePtr); + if (bcFramePtr->cmdObj) { + Tcl_DecrRefCount(bcFramePtr->cmdObj); + bcFramePtr->cmdObj = NULL; + bcFramePtr->cmd = NULL; + } iPtr->cmdFramePtr = bcFramePtr->nextPtr; if (iPtr->flags & INTERP_DEBUG_FRAME) { TclArgumentBCRelease((Tcl_Interp *) iPtr, bcFramePtr); @@ -8761,7 +8767,14 @@ TclGetSrcInfoForCmd( Interp *iPtr, int *lenPtr) { - CmdFrame *cfPtr = iPtr->cmdFramePtr; + return TclGetSrcInfoForCmdFrame(iPtr->cmdFramePtr, lenPtr); +} + +const char * +TclGetSrcInfoForCmdFrame( + CmdFrame *cfPtr, + int *lenPtr) +{ ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr; return GetSrcInfoForPc((unsigned char *) cfPtr->data.tebc.pc, @@ -8775,11 +8788,13 @@ TclGetSrcInfoForPc( ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr; assert(cfPtr->type == TCL_LOCATION_BC); - assert(cfPtr->cmd == NULL); + + if (cfPtr->cmd == NULL) { cfPtr->cmd = GetSrcInfoForPc( (unsigned char *) cfPtr->data.tebc.pc, codePtr, &cfPtr->len, NULL, NULL); + } assert(cfPtr->cmd != NULL); { diff --git a/generic/tclInt.h b/generic/tclInt.h index 99f1305..161d166 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1208,6 +1208,7 @@ typedef struct CmdFrame { const char *pc; /* ... and instruction pointer. */ } tebc; } data; + Tcl_Obj *cmdObj; const char *cmd; /* The executed command, if possible... */ int len; /* ... and its length. */ int numLevels; /* Value of interp's numLevels when the frame @@ -2907,7 +2908,11 @@ MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp, const char *modeString, int *seekFlagPtr, int *binaryPtr); MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr); +MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, int objc, + Tcl_Obj *const objv[]); MODULE_SCOPE const char *TclGetSrcInfoForCmd(Interp *iPtr, int *lenPtr); +MODULE_SCOPE const char *TclGetSrcInfoForCmdFrame(CmdFrame *cfPtr, + int *lenPtr); MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern, Tcl_Obj *unquotedPrefix, int globFlags, Tcl_GlobTypeData *types); -- cgit v0.12 From 9d7666659bb7ba5dcf54394bb4c2a555b2f46f7c Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 12 Aug 2013 20:00:14 +0000 Subject: Use a new flag value TCL_EVAL_SOURCE_IN_FRAME passed in by callers to determine whether the pre-subst source information in a CmdFrame is to be used. This takes the place of numLevels cross checking, so that field is removed. Routines are consolidated as well. --- generic/tclBasic.c | 43 +++++++++---------------------------------- generic/tclExecute.c | 13 ++----------- generic/tclInt.h | 8 +++----- 3 files changed, 14 insertions(+), 50 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 1cd2eae..b6c6f38 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -127,8 +127,6 @@ static Tcl_ObjCmdProc ExprSqrtFunc; static Tcl_ObjCmdProc ExprSrandFunc; static Tcl_ObjCmdProc ExprUnaryFunc; static Tcl_ObjCmdProc ExprWideFunc; -static Tcl_Obj * GetCommandSource(Interp *iPtr, int objc, - Tcl_Obj *const objv[]); static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected, int actual, Tcl_Obj *const *objv); static Tcl_NRPostProc NRCoroutineCallerCallback; @@ -149,7 +147,7 @@ static inline Command * TEOV_LookupCmdFromObj(Tcl_Interp *interp, static int TEOV_NotFound(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Namespace *lookupNsPtr); static int TEOV_RunEnterTraces(Tcl_Interp *interp, - Command **cmdPtrPtr, int objc, + Command **cmdPtrPtr, Tcl_Obj *commandPtr, int objc, Tcl_Obj *const objv[], Namespace *lookupNsPtr); static Tcl_NRPostProc RewindCoroutineCallback; static Tcl_NRPostProc TailcallCleanup; @@ -3353,31 +3351,6 @@ CancelEvalProc( /* *---------------------------------------------------------------------- * - * GetCommandSource -- - * - * This function returns a Tcl_Obj with the full source string for the - * command. This insures that traces get a correct NUL-terminated command - * string. - *---------------------------------------------------------------------- - */ - -static Tcl_Obj * -GetCommandSource( - Interp *iPtr, - int objc, - Tcl_Obj *const objv[]) -{ - CmdFrame *cfPtr = iPtr->cmdFramePtr; - - if (cfPtr && (cfPtr->numLevels != iPtr->numLevels-1)) { - cfPtr = NULL; - } - return TclGetSourceFromFrame(cfPtr, objc, objv); -} - -/* - *---------------------------------------------------------------------- - * * TclCleanupCommand -- * * This function frees up a Command structure unless it is still @@ -4230,7 +4203,9 @@ TclNREvalObjv( * necessary. */ - result = TEOV_RunEnterTraces(interp, &cmdPtr, objc, objv, lookupNsPtr); + result = TEOV_RunEnterTraces(interp, &cmdPtr, TclGetSourceFromFrame( + flags & TCL_EVAL_SOURCE_IN_FRAME ? iPtr->cmdFramePtr : NULL, + objc, objv), objc, objv, lookupNsPtr); if (!cmdPtr) { return TEOV_NotFound(interp, objc, objv, lookupNsPtr); } @@ -4644,6 +4619,7 @@ static int TEOV_RunEnterTraces( Tcl_Interp *interp, Command **cmdPtrPtr, + Tcl_Obj *commandPtr, int objc, Tcl_Obj *const objv[], Namespace *lookupNsPtr) @@ -4655,9 +4631,7 @@ TEOV_RunEnterTraces( int newEpoch; const char *command; int length; - Tcl_Obj *commandPtr; - commandPtr = GetCommandSource(iPtr, objc, objv); Tcl_IncrRefCount(commandPtr); command = Tcl_GetStringFromObj(commandPtr, &length); @@ -4989,7 +4963,6 @@ TclEvalEx( */ eeFramePtr->level = iPtr->cmdFramePtr ? iPtr->cmdFramePtr->level + 1 : 1; - eeFramePtr->numLevels = iPtr->numLevels; eeFramePtr->framePtr = iPtr->framePtr; eeFramePtr->nextPtr = iPtr->cmdFramePtr; eeFramePtr->nline = 0; @@ -5220,7 +5193,8 @@ TclEvalEx( eeFramePtr->line = lines; TclArgumentEnter(interp, objv, objectsUsed, eeFramePtr); - code = Tcl_EvalObjv(interp, objectsUsed, objv, TCL_EVAL_NOERR); + code = Tcl_EvalObjv(interp, objectsUsed, objv, + TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME); TclArgumentRelease(interp, objv, objectsUsed); eeFramePtr->line = NULL; @@ -5994,7 +5968,6 @@ TclNREvalObjEx( eoFramePtr->type = TCL_LOCATION_EVAL; eoFramePtr->level = (iPtr->cmdFramePtr == NULL? 1 : iPtr->cmdFramePtr->level + 1); - eoFramePtr->numLevels = iPtr->numLevels; eoFramePtr->framePtr = iPtr->framePtr; eoFramePtr->nextPtr = iPtr->cmdFramePtr; @@ -6004,6 +5977,8 @@ TclNREvalObjEx( eoFramePtr->data.eval.path = NULL; iPtr->cmdFramePtr = eoFramePtr; + + flags |= TCL_EVAL_SOURCE_IN_FRAME; } TclMarkTailcall(interp); diff --git a/generic/tclExecute.c b/generic/tclExecute.c index d8ccf40..58e4d3d 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -1998,7 +1998,6 @@ TclNRExecuteByteCode( bcFramePtr->type = ((codePtr->flags & TCL_BYTECODE_PRECOMPILED) ? TCL_LOCATION_PREBC : TCL_LOCATION_BC); bcFramePtr->level = (iPtr->cmdFramePtr ? iPtr->cmdFramePtr->level+1 : 1); - bcFramePtr->numLevels = iPtr->numLevels; bcFramePtr->framePtr = iPtr->framePtr; bcFramePtr->nextPtr = iPtr->cmdFramePtr; bcFramePtr->nline = 0; @@ -2906,7 +2905,7 @@ TEBCresume( pc += pcAdjustment; TEBC_YIELD(); return TclNREvalObjv(interp, objc, objv, - TCL_EVAL_NOERR, NULL); + TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME, NULL); #if TCL_SUPPORT_84_BYTECODE case INST_CALL_BUILTIN_FUNC1: @@ -8741,7 +8740,7 @@ IllegalExprOperandType( /* *---------------------------------------------------------------------- * - * TclGetSrcInfoForPc, GetSrcInfoForPc, TclGetSrcInfoForCmd -- + * TclGetSrcInfoForPc, GetSrcInfoForPc, TclGetSrcInfoForCmdFrame -- * * Given a program counter value, finds the closest command in the * bytecode code unit's CmdLocation array and returns information about @@ -8763,14 +8762,6 @@ IllegalExprOperandType( */ const char * -TclGetSrcInfoForCmd( - Interp *iPtr, - int *lenPtr) -{ - return TclGetSrcInfoForCmdFrame(iPtr->cmdFramePtr, lenPtr); -} - -const char * TclGetSrcInfoForCmdFrame( CmdFrame *cfPtr, int *lenPtr) diff --git a/generic/tclInt.h b/generic/tclInt.h index 161d166..19cd883 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1211,8 +1211,6 @@ typedef struct CmdFrame { Tcl_Obj *cmdObj; const char *cmd; /* The executed command, if possible... */ int len; /* ... and its length. */ - int numLevels; /* Value of interp's numLevels when the frame - * was pushed. */ const struct CFWordBC *litarg; /* Link to set of literal arguments which have * ben pushed on the lineLABCPtr stack by @@ -2200,8 +2198,9 @@ typedef struct Interp { * other than these should be turned into errors. */ -#define TCL_ALLOW_EXCEPTIONS 4 -#define TCL_EVAL_FILE 2 +#define TCL_ALLOW_EXCEPTIONS 0x04 +#define TCL_EVAL_FILE 0x02 +#define TCL_EVAL_SOURCE_IN_FRAME 0x10 /* * Flag bits for Interp structures: @@ -2910,7 +2909,6 @@ MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp, MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr); MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE const char *TclGetSrcInfoForCmd(Interp *iPtr, int *lenPtr); MODULE_SCOPE const char *TclGetSrcInfoForCmdFrame(CmdFrame *cfPtr, int *lenPtr); MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern, -- cgit v0.12 From 9c15217967a7614ac17d324144b8e39d788b6eef Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Aug 2013 04:13:21 +0000 Subject: Only schedule leave traces if enter traces complete successfully. This avoids a memleak, and opens a data slot, so we can pass objc, objv without the need to copy them into a list value. --- generic/tclBasic.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index b6c6f38..f852b44 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -4665,13 +4665,13 @@ TEOV_RunEnterTraces( *cmdPtrPtr = cmdPtr; } - if (cmdPtr) { + if (cmdPtr && (traceCode == TCL_OK)) { /* * Command was found: push a record to schedule the leave traces. */ - TclNRAddCallback(interp, TEOV_RunLeaveTraces, INT2PTR(traceCode), - commandPtr, cmdPtr, Tcl_NewListObj(objc, objv)); + TclNRAddCallback(interp, TEOV_RunLeaveTraces, INT2PTR(objc), + commandPtr, cmdPtr, objv); cmdPtr->refCount++; } else { Tcl_DecrRefCount(commandPtr); @@ -4686,19 +4686,18 @@ TEOV_RunLeaveTraces( int result) { Interp *iPtr = (Interp *) interp; - const char *command; - int length, objc; - Tcl_Obj **objv; - int traceCode = PTR2INT(data[0]); + int traceCode = TCL_OK; + int objc = PTR2INT(data[0]); Tcl_Obj *commandPtr = data[1]; Command *cmdPtr = data[2]; - Tcl_Obj *wordsPtr = data[3]; + Tcl_Obj **objv = data[3]; - command = Tcl_GetStringFromObj(commandPtr, &length); - Tcl_ListObjGetElements(NULL, wordsPtr, &objc, &objv); if (!(cmdPtr->flags & CMD_IS_DELETED)) { - if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) && traceCode == TCL_OK){ + int length; + const char *command = Tcl_GetStringFromObj(commandPtr, &length); + + if (cmdPtr->flags & CMD_HAS_EXEC_TRACES){ traceCode = TclCheckExecutionTraces(interp, command, length, cmdPtr, result, TCL_TRACE_LEAVE_EXEC, objc, objv); } @@ -4708,7 +4707,6 @@ TEOV_RunLeaveTraces( } } Tcl_DecrRefCount(commandPtr); - Tcl_DecrRefCount(wordsPtr); /* * As cmdPtr is set, TclNRRunCallbacks is about to reduce the numlevels. -- cgit v0.12 From b2d7315f923bd7c0eae390595466fcf0ff1388ac Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Aug 2013 12:15:59 +0000 Subject: Consolidate some helper routines. --- generic/tclCmdIL.c | 19 ------------------- generic/tclExecute.c | 27 +++++++++++++++++++-------- generic/tclInt.h | 2 -- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index da9edd6..fa4ead4 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -1266,25 +1266,6 @@ InfoFrameCmd( */ Tcl_Obj * -TclGetSourceFromFrame( - CmdFrame *cfPtr, - int objc, - Tcl_Obj *const objv[]) -{ - if (cfPtr == NULL) { - return Tcl_NewListObj(objc, objv); - } - if (cfPtr->cmdObj == NULL) { - if (cfPtr->cmd == NULL) { - cfPtr->cmd = TclGetSrcInfoForCmdFrame(cfPtr, &cfPtr->len); - } - cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len); - Tcl_IncrRefCount(cfPtr->cmdObj); - } - return cfPtr->cmdObj; -} - -Tcl_Obj * TclInfoFrame( Tcl_Interp *interp, /* Current interpreter. */ CmdFrame *framePtr) /* Frame to get info for. */ diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 58e4d3d..d066476 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -8740,7 +8740,7 @@ IllegalExprOperandType( /* *---------------------------------------------------------------------- * - * TclGetSrcInfoForPc, GetSrcInfoForPc, TclGetSrcInfoForCmdFrame -- + * TclGetSrcInfoForPc, GetSrcInfoForPc, TclGetSourceFromFrame -- * * Given a program counter value, finds the closest command in the * bytecode code unit's CmdLocation array and returns information about @@ -8761,15 +8761,26 @@ IllegalExprOperandType( *---------------------------------------------------------------------- */ -const char * -TclGetSrcInfoForCmdFrame( +Tcl_Obj * +TclGetSourceFromFrame( CmdFrame *cfPtr, - int *lenPtr) + int objc, + Tcl_Obj *const objv[]) { - ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr; - - return GetSrcInfoForPc((unsigned char *) cfPtr->data.tebc.pc, - codePtr, lenPtr, NULL, NULL); + if (cfPtr == NULL) { + return Tcl_NewListObj(objc, objv); + } + if (cfPtr->cmdObj == NULL) { + if (cfPtr->cmd == NULL) { + ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr; + + cfPtr->cmd = GetSrcInfoForPc((unsigned char *) + cfPtr->data.tebc.pc, codePtr, &cfPtr->len, NULL, NULL); + } + cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len); + Tcl_IncrRefCount(cfPtr->cmdObj); + } + return cfPtr->cmdObj; } void diff --git a/generic/tclInt.h b/generic/tclInt.h index 19cd883..6056119 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2909,8 +2909,6 @@ MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp, MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr); MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE const char *TclGetSrcInfoForCmdFrame(CmdFrame *cfPtr, - int *lenPtr); MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern, Tcl_Obj *unquotedPrefix, int globFlags, Tcl_GlobTypeData *types); -- cgit v0.12