summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2013-08-10 05:16:38 (GMT)
committerdgp <dgp@users.sourceforge.net>2013-08-10 05:16:38 (GMT)
commitde857ca207e4dceea586bf2dbfe497df4d9d02c8 (patch)
tree8047783a9771beff85554397a4263d1d93acde9b /generic/tclBasic.c
parentfec32bb50c597bfbb21ad55211339355034f6d55 (diff)
downloadtcl-de857ca207e4dceea586bf2dbfe497df4d9d02c8.zip
tcl-de857ca207e4dceea586bf2dbfe497df4d9d02c8.tar.gz
tcl-de857ca207e4dceea586bf2dbfe497df4d9d02c8.tar.bz2
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.
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c41
1 files changed, 15 insertions, 26 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;