summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c1170
1 files changed, 71 insertions, 1099 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index b39d346..5a3347e 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -83,15 +83,11 @@ TCL_DECLARE_MUTEX(cancelLock)
#define SAVE_CONTEXT(context) \
(context).framePtr = iPtr->framePtr; \
- (context).varFramePtr = iPtr->varFramePtr; \
- (context).cmdFramePtr = iPtr->cmdFramePtr; \
- (context).lineLABCPtr = iPtr->lineLABCPtr
+ (context).varFramePtr = iPtr->varFramePtr
#define RESTORE_CONTEXT(context) \
iPtr->framePtr = (context).framePtr; \
- iPtr->varFramePtr = (context).varFramePtr; \
- iPtr->cmdFramePtr = (context).cmdFramePtr; \
- iPtr->lineLABCPtr = (context).lineLABCPtr
+ iPtr->varFramePtr = (context).varFramePtr
/*
* Static functions in this file:
@@ -165,6 +161,31 @@ static Tcl_ObjCmdProc NRCoroInjectObjCmd;
MODULE_SCOPE const TclStubs tclStubs;
+static void UpdateStringOfScriptSource(Tcl_Obj *objPtr);
+
+static const Tcl_ObjType scriptSourceType = {
+ "scriptSource", /* name */
+ NULL, /* freeIntRepProc */
+ NULL, /* dupIntRepProc */
+ UpdateStringOfScriptSource, /* updateStringProc */
+ NULL /* setFromAnyProc */
+};
+
+static void
+UpdateStringOfScriptSource(
+ Tcl_Obj *objPtr)
+{
+ const char *bytes = objPtr->internalRep.twoPtrValue.ptr1;
+ int len = PTR2INT(objPtr->internalRep.twoPtrValue.ptr2);
+
+ if (bytes) {
+ objPtr->bytes = (char *) ckalloc((unsigned) len + 1);
+ memcpy(objPtr->bytes, bytes, len);
+ objPtr->bytes[len] = '\0';
+ objPtr->length = len;
+ }
+}
+
/*
* Magical counts for the number of arguments accepted by a coroutine command
* after particular kinds of [yield].
@@ -514,39 +535,12 @@ Tcl_CreateInterp(void)
iPtr->framePtr = NULL; /* Initialise as soon as :: is available */
iPtr->varFramePtr = NULL; /* Initialise as soon as :: is available */
- /*
- * TIP #280 - Initialize the arrays used to extend the ByteCode and Proc
- * structures.
- */
-
- iPtr->cmdFramePtr = NULL;
- iPtr->linePBodyPtr = ckalloc(sizeof(Tcl_HashTable));
- iPtr->lineBCPtr = ckalloc(sizeof(Tcl_HashTable));
- iPtr->lineLAPtr = ckalloc(sizeof(Tcl_HashTable));
- iPtr->lineLABCPtr = ckalloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(iPtr->linePBodyPtr, TCL_ONE_WORD_KEYS);
- Tcl_InitHashTable(iPtr->lineBCPtr, TCL_ONE_WORD_KEYS);
- Tcl_InitHashTable(iPtr->lineLAPtr, TCL_ONE_WORD_KEYS);
- Tcl_InitHashTable(iPtr->lineLABCPtr, TCL_ONE_WORD_KEYS);
- iPtr->scriptCLLocPtr = NULL;
-
iPtr->activeVarTracePtr = NULL;
iPtr->returnOpts = NULL;
iPtr->errorInfo = NULL;
TclNewLiteralStringObj(iPtr->eiVar, "::errorInfo");
Tcl_IncrRefCount(iPtr->eiVar);
- iPtr->errorStack = Tcl_NewListObj(0, NULL);
- Tcl_IncrRefCount(iPtr->errorStack);
- iPtr->resetErrorStack = 1;
- TclNewLiteralStringObj(iPtr->upLiteral,"UP");
- Tcl_IncrRefCount(iPtr->upLiteral);
- TclNewLiteralStringObj(iPtr->callLiteral,"CALL");
- Tcl_IncrRefCount(iPtr->callLiteral);
- TclNewLiteralStringObj(iPtr->innerLiteral,"INNER");
- Tcl_IncrRefCount(iPtr->innerLiteral);
- iPtr->innerContext = Tcl_NewListObj(0, NULL);
- Tcl_IncrRefCount(iPtr->innerContext);
iPtr->errorCode = NULL;
TclNewLiteralStringObj(iPtr->ecVar, "::errorCode");
Tcl_IncrRefCount(iPtr->ecVar);
@@ -734,6 +728,8 @@ Tcl_CreateInterp(void)
iPtr->asyncReadyPtr = TclGetAsyncReadyPtr();
iPtr->deferredCallbacks = NULL;
+ iPtr->cmdSourcePtr = NULL;
+
/*
* Create the core commands. Do it here, rather than calling
* Tcl_CreateCommand, because it's faster (there's no need to check for a
@@ -1345,7 +1341,6 @@ DeleteInterpProc(
Tcl_HashSearch search;
Tcl_HashTable *hTablePtr;
ResolverScheme *resPtr, *nextResPtr;
- int i;
/*
* Punt if there is an error in the Tcl_Release/Tcl_Preserve matchup,
@@ -1502,12 +1497,6 @@ DeleteInterpProc(
Tcl_DecrRefCount(iPtr->errorInfo);
iPtr->errorInfo = NULL;
}
- Tcl_DecrRefCount(iPtr->errorStack);
- iPtr->errorStack = NULL;
- Tcl_DecrRefCount(iPtr->upLiteral);
- Tcl_DecrRefCount(iPtr->callLiteral);
- Tcl_DecrRefCount(iPtr->innerLiteral);
- Tcl_DecrRefCount(iPtr->innerContext);
if (iPtr->returnOpts) {
Tcl_DecrRefCount(iPtr->returnOpts);
}
@@ -1545,92 +1534,6 @@ DeleteInterpProc(
TclDeleteLiteralTable(interp, &iPtr->literalTable);
/*
- * TIP #280 - Release the arrays for ByteCode/Proc extension, and
- * contents.
- */
-
- for (hPtr = Tcl_FirstHashEntry(iPtr->linePBodyPtr, &search);
- hPtr != NULL;
- hPtr = Tcl_NextHashEntry(&search)) {
- CmdFrame *cfPtr = Tcl_GetHashValue(hPtr);
- Proc *procPtr = (Proc *) Tcl_GetHashKey(iPtr->linePBodyPtr, hPtr);
-
- procPtr->iPtr = NULL;
- if (cfPtr) {
- if (cfPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount(cfPtr->data.eval.path);
- }
- ckfree(cfPtr->line);
- ckfree(cfPtr);
- }
- Tcl_DeleteHashEntry(hPtr);
- }
- Tcl_DeleteHashTable(iPtr->linePBodyPtr);
- ckfree(iPtr->linePBodyPtr);
- iPtr->linePBodyPtr = NULL;
-
- /*
- * See also tclCompile.c, TclCleanupByteCode
- */
-
- for (hPtr = Tcl_FirstHashEntry(iPtr->lineBCPtr, &search);
- hPtr != NULL;
- hPtr = Tcl_NextHashEntry(&search)) {
- ExtCmdLoc *eclPtr = Tcl_GetHashValue(hPtr);
-
- if (eclPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount(eclPtr->path);
- }
- for (i=0; i< eclPtr->nuloc; i++) {
- ckfree(eclPtr->loc[i].line);
- }
-
- if (eclPtr->loc != NULL) {
- ckfree(eclPtr->loc);
- }
-
- Tcl_DeleteHashTable(&eclPtr->litInfo);
-
- ckfree(eclPtr);
- Tcl_DeleteHashEntry(hPtr);
- }
- Tcl_DeleteHashTable(iPtr->lineBCPtr);
- ckfree(iPtr->lineBCPtr);
- iPtr->lineBCPtr = NULL;
-
- /*
- * Location stack for uplevel/eval/... scripts which were passed through
- * proc arguments. Actually we track all arguments as we do not and cannot
- * know which arguments will be used as scripts and which will not.
- */
-
- if (iPtr->lineLAPtr->numEntries && !TclInExit()) {
- /*
- * When the interp goes away we have nothing on the stack, so there
- * are no arguments, so this table has to be empty.
- */
-
- Tcl_Panic("Argument location tracking table not empty");
- }
-
- Tcl_DeleteHashTable(iPtr->lineLAPtr);
- ckfree((char *) iPtr->lineLAPtr);
- iPtr->lineLAPtr = NULL;
-
- if (iPtr->lineLABCPtr->numEntries && !TclInExit()) {
- /*
- * When the interp goes away we have nothing on the stack, so there
- * are no arguments, so this table has to be empty.
- */
-
- Tcl_Panic("Argument location tracking table not empty");
- }
-
- Tcl_DeleteHashTable(iPtr->lineLABCPtr);
- ckfree(iPtr->lineLABCPtr);
- iPtr->lineLABCPtr = NULL;
-
- /*
* Squelch the tables of traces on variables and searches over arrays in
* the in the interpreter.
*/
@@ -3359,34 +3262,26 @@ GetCommandSource(
Tcl_Obj *const objv[],
int lookup)
{
- Tcl_Obj *objPtr, *obj2Ptr;
- CmdFrame *cfPtr = iPtr->cmdFramePtr;
- const char *command = NULL;
- int numChars;
-
- objPtr = Tcl_NewListObj(objc, objv);
- if (lookup && cfPtr && (cfPtr->numLevels == iPtr->numLevels-1)) {
- switch (cfPtr->type) {
- case TCL_LOCATION_EVAL:
- case TCL_LOCATION_SOURCE:
- command = cfPtr->cmd.str.cmd;
- numChars = cfPtr->cmd.str.len;
- break;
- case TCL_LOCATION_BC:
- case TCL_LOCATION_PREBC:
- command = TclGetSrcInfoForCmd(iPtr, &numChars);
- break;
- case TCL_LOCATION_EVAL_LIST:
- /* Got it already */
- break;
- }
- if (command) {
- obj2Ptr = Tcl_NewStringObj(command, numChars);
- objPtr->bytes = obj2Ptr->bytes;
- objPtr->length = numChars;
- obj2Ptr->bytes = NULL;
- Tcl_DecrRefCount(obj2Ptr);
- }
+ Tcl_Obj *objPtr = Tcl_NewListObj(objc, objv);
+
+ if (iPtr->cmdSourcePtr) {
+ char *command;
+ int len;
+ char *orig = iPtr->cmdSourcePtr->bytes;
+
+ command = Tcl_GetStringFromObj(iPtr->cmdSourcePtr, &len);
+ objPtr->bytes = (char *) ckalloc((unsigned) len + 1);
+ strcpy(objPtr->bytes, command);
+ objPtr->length = len;
+
+ /*
+ * Avoid leaving a string rep if none was there.
+ */
+
+ if (orig == NULL) {
+ TclInvalidateStringRep(iPtr->cmdSourcePtr);
+ }
+
}
Tcl_IncrRefCount(objPtr);
return objPtr;
@@ -4255,6 +4150,7 @@ TclNREvalObjv(
return result;
}
}
+ iPtr->cmdSourcePtr = NULL;
#ifdef USE_DTRACE
@@ -4268,14 +4164,6 @@ TclNREvalObjv(
TCL_DTRACE_CMD_ARGS(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
a[8], a[9]);
}
- if (TCL_DTRACE_CMD_INFO_ENABLED() && iPtr->cmdFramePtr) {
- Tcl_Obj *info = TclInfoFrame(interp, iPtr->cmdFramePtr);
- const char *a[6]; int i[2];
-
- TclDTraceInfo(info, a, i);
- TCL_DTRACE_CMD_INFO(a[0], a[1], a[2], a[3], i[0], i[1], a[4], a[5]);
- TclDecrRefCount(info);
- }
if (TCL_DTRACE_CMD_RETURN_ENABLED() || TCL_DTRACE_CMD_RESULT_ENABLED()) {
TclNRAddCallback(interp, DTraceCmdReturn, objv[0], NULL, NULL, NULL);
}
@@ -4815,8 +4703,7 @@ Tcl_EvalTokensStandard(
int count) /* Number of tokens to consider at tokenPtr.
* Must be at least 1. */
{
- return TclSubstTokens(interp, tokenPtr, count, /* numLeftPtr */ NULL, 1,
- NULL, NULL);
+ return TclSubstTokens(interp, tokenPtr, count, /* numLeftPtr */ NULL);
}
/*
@@ -4884,7 +4771,6 @@ Tcl_EvalTokens(
* Side effects:
* Depends on the script.
*
- * TIP #280 : Keep public API, internally extended API.
*----------------------------------------------------------------------
*/
@@ -4900,44 +4786,11 @@ Tcl_EvalEx(
* evaluation of the script. Only
* TCL_EVAL_GLOBAL is currently supported. */
{
- return TclEvalEx(interp, script, numBytes, flags, 1, NULL, script);
-}
-
-int
-TclEvalEx(
- Tcl_Interp *interp, /* Interpreter in which to evaluate the
- * script. Also used for error reporting. */
- const char *script, /* First character of script to evaluate. */
- int numBytes, /* Number of bytes in script. If < 0, the
- * script consists of all bytes up to the
- * first NUL character. */
- int flags, /* Collection of OR-ed bits that control the
- * evaluation of the script. Only
- * TCL_EVAL_GLOBAL is currently supported. */
- int line, /* The line the script starts on. */
- int *clNextOuter, /* Information about an outer context for */
- const char *outerScript) /* continuation line data. This is set only in
- * TclSubstTokens(), to properly handle
- * [...]-nested commands. The 'outerScript'
- * refers to the most-outer script containing
- * the embedded command, which is refered to
- * by 'script'. The 'clNextOuter' refers to
- * the current entry in the table of
- * continuation lines in this "master script",
- * and the character offsets are relative to
- * the 'outerScript' as well.
- *
- * If outerScript == script, then this call is
- * for the outer-most script/command. See
- * Tcl_EvalEx() and TclEvalObjEx() for places
- * generating arguments for which this is
- * true. */
-{
Interp *iPtr = (Interp *) interp;
const char *p, *next;
const unsigned int minObjs = 20;
Tcl_Obj **objv, **objvSpace;
- int *expand, *lines, *lineSpace;
+ int *expand;
Tcl_Token *tokenPtr;
int commandLength, bytesLeft, expandRequested, code = TCL_OK;
CallFrame *savedVarFramePtr;/* Saves old copy of iPtr->varFramePtr in case
@@ -4950,28 +4803,9 @@ TclEvalEx(
* the script, so that it can be freed
* properly if an error occurs. */
Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse));
- CmdFrame *eeFramePtr = TclStackAlloc(interp, sizeof(CmdFrame));
Tcl_Obj **stackObjArray =
TclStackAlloc(interp, minObjs * sizeof(Tcl_Obj *));
int *expandStack = TclStackAlloc(interp, minObjs * sizeof(int));
- int *linesStack = TclStackAlloc(interp, minObjs * sizeof(int));
- /* TIP #280 Structures for tracking of command
- * locations. */
- int *clNext = NULL; /* Pointer for the tracking of invisible
- * continuation lines. Initialized only if the
- * caller gave us a table of locations to
- * track, via scriptCLLocPtr. It always refers
- * to the table entry holding the location of
- * the next invisible continuation line to
- * look for, while parsing the script. */
-
- if (iPtr->scriptCLLocPtr) {
- if (clNextOuter) {
- clNext = clNextOuter;
- } else {
- clNext = &iPtr->scriptCLLocPtr->loc[0];
- }
- }
if (numBytes < 0) {
numBytes = strlen(script);
@@ -4989,77 +4823,10 @@ TclEvalEx(
*/
objv = objvSpace = stackObjArray;
- lines = lineSpace = linesStack;
expand = expandStack;
p = script;
bytesLeft = numBytes;
- /*
- * TIP #280 Initialize tracking. Do not push on the frame stack yet.
- *
- * We may continue counting based on a specific context (CTX), or open a
- * new context, either for a sourced script, or 'eval'. For sourced files
- * we always have a path object, even if nothing was specified in the
- * interp itself. That makes code using it simpler as NULL checks can be
- * left out. Sourced file without path in the 'scriptFile' is possible
- * during Tcl initialization.
- */
-
- eeFramePtr->level = iPtr->cmdFramePtr ? iPtr->cmdFramePtr->level + 1 : 1;
- eeFramePtr->numLevels = iPtr->numLevels;
- eeFramePtr->framePtr = iPtr->framePtr;
- eeFramePtr->nextPtr = iPtr->cmdFramePtr;
- eeFramePtr->nline = 0;
- eeFramePtr->line = NULL;
-
- iPtr->cmdFramePtr = eeFramePtr;
- if (iPtr->evalFlags & TCL_EVAL_CTX) {
- /*
- * Path information comes out of the context.
- */
-
- eeFramePtr->type = TCL_LOCATION_SOURCE;
- eeFramePtr->data.eval.path = iPtr->invokeCmdFramePtr->data.eval.path;
- Tcl_IncrRefCount(eeFramePtr->data.eval.path);
- } else if (iPtr->evalFlags & TCL_EVAL_FILE) {
- /*
- * Set up for a sourced file.
- */
-
- eeFramePtr->type = TCL_LOCATION_SOURCE;
-
- if (iPtr->scriptFile) {
- /*
- * Normalization here, to have the correct pwd. Should have
- * negligible impact on performance, as the norm should have been
- * done already by the 'source' invoking us, and it caches the
- * result.
- */
-
- Tcl_Obj *norm = Tcl_FSGetNormalizedPath(interp, iPtr->scriptFile);
-
- if (norm == NULL) {
- /*
- * Error message in the interp result.
- */
-
- code = TCL_ERROR;
- goto error;
- }
- eeFramePtr->data.eval.path = norm;
- } else {
- TclNewLiteralStringObj(eeFramePtr->data.eval.path, "");
- }
- Tcl_IncrRefCount(eeFramePtr->data.eval.path);
- } else {
- /*
- * Set up for plain eval.
- */
-
- eeFramePtr->type = TCL_LOCATION_EVAL;
- eeFramePtr->data.eval.path = NULL;
- }
-
iPtr->evalFlags = 0;
do {
if (Tcl_ParseCommand(interp, p, bytesLeft, 0, parsePtr) != TCL_OK) {
@@ -5067,28 +4834,8 @@ TclEvalEx(
goto error;
}
- /*
- * TIP #280 Track lines. The parser may have skipped text till it
- * found the command we are now at. We have to count the lines in this
- * block, and do not forget invisible continuation lines.
- */
-
- TclAdvanceLines(&line, p, parsePtr->commandStart);
- TclAdvanceContinuations(&line, &clNext,
- parsePtr->commandStart - outerScript);
-
gotParse = 1;
if (parsePtr->numWords > 0) {
- /*
- * TIP #280. Track lines within the words of the current
- * command. We use a separate pointer into the table of
- * continuation line locations to not lose our position for the
- * per-command parsing.
- */
-
- int wordLine = line;
- const char *wordStart = parsePtr->commandStart;
- int *wordCLNext = clNext;
unsigned int objectsNeeded = 0;
unsigned int numWords = parsePtr->numWords;
@@ -5099,39 +4846,15 @@ TclEvalEx(
if (numWords > minObjs) {
expand = ckalloc(numWords * sizeof(int));
objvSpace = ckalloc(numWords * sizeof(Tcl_Obj *));
- lineSpace = ckalloc(numWords * sizeof(int));
}
expandRequested = 0;
objv = objvSpace;
- lines = lineSpace;
- iPtr->cmdFramePtr = eeFramePtr->nextPtr;
for (objectsUsed = 0, tokenPtr = parsePtr->tokenPtr;
objectsUsed < numWords;
objectsUsed++, tokenPtr += tokenPtr->numComponents+1) {
- /*
- * TIP #280. Track lines to current word. Save the information
- * on a per-word basis, signaling dynamic words as needed.
- * Make the information available to the recursively called
- * evaluator as well, including the type of context (source
- * vs. eval).
- */
-
- TclAdvanceLines(&wordLine, wordStart, tokenPtr->start);
- TclAdvanceContinuations(&wordLine, &wordCLNext,
- tokenPtr->start - outerScript);
- wordStart = tokenPtr->start;
-
- lines[objectsUsed] = TclWordKnownAtCompileTime(tokenPtr, NULL)
- ? wordLine : -1;
-
- if (eeFramePtr->type == TCL_LOCATION_SOURCE) {
- iPtr->evalFlags |= TCL_EVAL_FILE;
- }
-
code = TclSubstTokens(interp, tokenPtr+1,
- tokenPtr->numComponents, NULL, wordLine,
- wordCLNext, outerScript);
+ tokenPtr->numComponents, NULL);
iPtr->evalFlags = 0;
@@ -5164,12 +4887,7 @@ TclEvalEx(
objectsNeeded++;
}
- if (wordCLNext) {
- TclContinuationsEnterDerived(objv[objectsUsed],
- wordStart - outerScript, wordCLNext);
- }
} /* for loop */
- iPtr->cmdFramePtr = eeFramePtr;
if (code != TCL_OK) {
goto error;
}
@@ -5179,14 +4897,12 @@ TclEvalEx(
*/
Tcl_Obj **copy = objvSpace;
- int *lcopy = lineSpace;
int wordIdx = numWords;
int objIdx = objectsNeeded - 1;
if ((numWords > minObjs) || (objectsNeeded > minObjs)) {
objv = objvSpace =
ckalloc(objectsNeeded * sizeof(Tcl_Obj *));
- lines = lineSpace = ckalloc(objectsNeeded * sizeof(int));
}
objectsUsed = 0;
@@ -5199,13 +4915,11 @@ TclEvalEx(
&elements);
objectsUsed += numElements;
while (numElements--) {
- lines[objIdx] = -1;
objv[objIdx--] = elements[numElements];
Tcl_IncrRefCount(elements[numElements]);
}
Tcl_DecrRefCount(temp);
} else {
- lines[objIdx] = lcopy[wordIdx];
objv[objIdx--] = copy[wordIdx];
objectsUsed++;
}
@@ -5215,38 +4929,25 @@ TclEvalEx(
if (copy != stackObjArray) {
ckfree(copy);
}
- if (lcopy != linesStack) {
- ckfree(lcopy);
- }
}
/*
* Execute the command and free the objects for its words.
- *
- * TIP #280: Remember the command itself for 'info frame'. We
- * shorten the visible command by one char to exclude the
- * termination character, if necessary. Here is where we put our
- * frame on the stack of frames too. _After_ the nested commands
- * have been executed.
*/
- eeFramePtr->cmd.str.cmd = parsePtr->commandStart;
- eeFramePtr->cmd.str.len = parsePtr->commandSize;
-
- if (parsePtr->term ==
- parsePtr->commandStart + parsePtr->commandSize - 1) {
- eeFramePtr->cmd.str.len--;
- }
+ {
+ Tcl_Obj *srcPtr = Tcl_NewObj();
- eeFramePtr->nline = objectsUsed;
- eeFramePtr->line = lines;
+ srcPtr->bytes = NULL;
+ srcPtr->typePtr = &scriptSourceType;
+ srcPtr->internalRep.twoPtrValue.ptr1 = (char *) script;
+ srcPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(numBytes);
+ iPtr->cmdSourcePtr = srcPtr;
- TclArgumentEnter(interp, objv, objectsUsed, eeFramePtr);
- code = Tcl_EvalObjv(interp, objectsUsed, objv, TCL_EVAL_NOERR);
- TclArgumentRelease(interp, objv, objectsUsed);
+ code = Tcl_EvalObjv(interp, objectsUsed, objv, TCL_EVAL_NOERR);
- eeFramePtr->line = NULL;
- eeFramePtr->nline = 0;
+ Tcl_DecrRefCount(srcPtr);
+ }
if (code != TCL_OK) {
goto error;
@@ -5258,8 +4959,6 @@ TclEvalEx(
if (objvSpace != stackObjArray) {
ckfree(objvSpace);
objvSpace = stackObjArray;
- ckfree(lineSpace);
- lineSpace = linesStack;
}
/*
@@ -5275,15 +4974,11 @@ TclEvalEx(
/*
* Advance to the next command in the script.
- *
- * TIP #280 Track Lines. Now we track how many lines were in the
- * executed command.
*/
next = parsePtr->commandStart + parsePtr->commandSize;
bytesLeft -= next - p;
p = next;
- TclAdvanceLines(&line, parsePtr->commandStart, p);
Tcl_FreeParse(parsePtr);
gotParse = 0;
} while (bytesLeft > 0);
@@ -5334,7 +5029,6 @@ TclEvalEx(
}
if (objvSpace != stackObjArray) {
ckfree(objvSpace);
- ckfree(lineSpace);
}
if (expand != expandStack) {
ckfree(expand);
@@ -5342,18 +5036,8 @@ TclEvalEx(
iPtr->varFramePtr = savedVarFramePtr;
cleanup_return:
- /*
- * TIP #280. Release the local CmdFrame, and its contents.
- */
-
- iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr;
- if (eeFramePtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount(eeFramePtr->data.eval.path);
- }
- TclStackFree(interp, linesStack);
TclStackFree(interp, expandStack);
TclStackFree(interp, stackObjArray);
- TclStackFree(interp, eeFramePtr);
TclStackFree(interp, parsePtr);
return code;
@@ -5362,436 +5046,6 @@ TclEvalEx(
/*
*----------------------------------------------------------------------
*
- * TclAdvanceLines --
- *
- * This function is a helper which counts the number of lines in a block
- * of text and advances an external counter.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The specified counter is advanced per the number of lines found.
- *
- * TIP #280
- *----------------------------------------------------------------------
- */
-
-void
-TclAdvanceLines(
- int *line,
- const char *start,
- const char *end)
-{
- register const char *p;
-
- for (p = start; p < end; p++) {
- if (*p == '\n') {
- (*line)++;
- }
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclAdvanceContinuations --
- *
- * This procedure is a helper which counts the number of continuation
- * lines (CL) in a block of text using a table of CL locations and
- * advances an external counter, and the pointer into the table.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The specified counter is advanced per the number of continuation lines
- * found.
- *
- * TIP #280
- *----------------------------------------------------------------------
- */
-
-void
-TclAdvanceContinuations(
- int *line,
- int **clNextPtrPtr,
- int loc)
-{
- /*
- * Track the invisible continuation lines embedded in a script, if any.
- * Here they are just spaces (already). They were removed by
- * TclSubstTokens via TclParseBackslash.
- *
- * *clNextPtrPtr <=> We have continuation lines to track.
- * **clNextPtrPtr >= 0 <=> We are not beyond the last possible location.
- * loc >= **clNextPtrPtr <=> We stepped beyond the current cont. line.
- */
-
- while (*clNextPtrPtr && (**clNextPtrPtr >= 0)
- && (loc >= **clNextPtrPtr)) {
- /*
- * We just stepped over an invisible continuation line. Adjust the
- * line counter and step to the table entry holding the location of
- * the next continuation line to track.
- */
-
- (*line)++;
- (*clNextPtrPtr)++;
- }
-}
-
-/*
- *----------------------------------------------------------------------
- * Note: The whole data structure access for argument location tracking is
- * hidden behind these three functions. The only parts open are the lineLAPtr
- * field in the Interp structure. The CFWord definition is internal to here.
- * Should make it easier to redo the data structures if we find something more
- * space/time efficient.
- */
-
-/*
- *----------------------------------------------------------------------
- *
- * TclArgumentEnter --
- *
- * This procedure is a helper for the TIP #280 uplevel extension. It
- * enters location references for the arguments of a command to be
- * invoked. Only the first entry has the actual data, further entries
- * simply count the usage up.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May allocate memory.
- *
- * TIP #280
- *----------------------------------------------------------------------
- */
-
-void
-TclArgumentEnter(
- Tcl_Interp *interp,
- Tcl_Obj **objv,
- int objc,
- CmdFrame *cfPtr)
-{
- Interp *iPtr = (Interp *) interp;
- int new, i;
- Tcl_HashEntry *hPtr;
- CFWord *cfwPtr;
-
- for (i = 1; i < objc; i++) {
- /*
- * Ignore argument words without line information (= dynamic). If they
- * are variables they may have location information associated with
- * that, either through globally recorded 'set' invokations, or
- * literals in bytecode. Eitehr way there is no need to record
- * something here.
- */
-
- if (cfPtr->line[i] < 0) {
- continue;
- }
- hPtr = Tcl_CreateHashEntry(iPtr->lineLAPtr, objv[i], &new);
- if (new) {
- /*
- * The word is not on the stack yet, remember the current location
- * and initialize references.
- */
-
- cfwPtr = ckalloc(sizeof(CFWord));
- cfwPtr->framePtr = cfPtr;
- cfwPtr->word = i;
- cfwPtr->refCount = 1;
- Tcl_SetHashValue(hPtr, cfwPtr);
- } else {
- /*
- * The word is already on the stack, its current location is not
- * relevant. Just remember the reference to prevent early removal.
- */
-
- cfwPtr = Tcl_GetHashValue(hPtr);
- cfwPtr->refCount++;
- }
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclArgumentRelease --
- *
- * This procedure is a helper for the TIP #280 uplevel extension. It
- * removes the location references for the arguments of a command just
- * done. Usage is counted down, the data is removed only when no user is
- * left over.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May release memory.
- *
- * TIP #280
- *----------------------------------------------------------------------
- */
-
-void
-TclArgumentRelease(
- Tcl_Interp *interp,
- Tcl_Obj **objv,
- int objc)
-{
- Interp *iPtr = (Interp *) interp;
- int i;
-
- for (i = 1; i < objc; i++) {
- CFWord *cfwPtr;
- Tcl_HashEntry *hPtr =
- Tcl_FindHashEntry(iPtr->lineLAPtr, (char *) objv[i]);
-
- if (!hPtr) {
- continue;
- }
- cfwPtr = Tcl_GetHashValue(hPtr);
-
- cfwPtr->refCount--;
- if (cfwPtr->refCount > 0) {
- continue;
- }
-
- ckfree(cfwPtr);
- Tcl_DeleteHashEntry(hPtr);
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclArgumentBCEnter --
- *
- * This procedure is a helper for the TIP #280 uplevel extension. It
- * enters location references for the literal arguments of commands in
- * bytecode about to be invoked. Only the first entry has the actual
- * data, further entries simply count the usage up.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May allocate memory.
- *
- * TIP #280
- *----------------------------------------------------------------------
- */
-
-void
-TclArgumentBCEnter(
- Tcl_Interp *interp,
- Tcl_Obj *objv[],
- int objc,
- void *codePtr,
- CmdFrame *cfPtr,
- int pc)
-{
- Interp *iPtr = (Interp *) interp;
- Tcl_HashEntry *hePtr =
- Tcl_FindHashEntry(iPtr->lineBCPtr, (char *) codePtr);
- ExtCmdLoc *eclPtr;
-
- if (!hePtr) {
- return;
- }
- eclPtr = Tcl_GetHashValue(hePtr);
- hePtr = Tcl_FindHashEntry(&eclPtr->litInfo, INT2PTR(pc));
- if (hePtr) {
- int word;
- int cmd = PTR2INT(Tcl_GetHashValue(hePtr));
- ECL *ePtr = &eclPtr->loc[cmd];
- CFWordBC *lastPtr = NULL;
-
- /*
- * A few truths ...
- * (1) ePtr->nline == objc
- * (2) (ePtr->line[word] < 0) => !literal, for all words
- * (3) (word == 0) => !literal
- *
- * Item (2) is why we can use objv to get the literals, and do not
- * have to save them at compile time.
- */
-
- if (ePtr->nline != objc) {
- Tcl_Panic ("TIP 280 data structure inconsistency");
- }
-
- for (word = 1; word < objc; word++) {
- if (ePtr->line[word] >= 0) {
- int isnew;
- Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(iPtr->lineLABCPtr,
- objv[word], &isnew);
- CFWordBC *cfwPtr = ckalloc(sizeof(CFWordBC));
-
- cfwPtr->framePtr = cfPtr;
- cfwPtr->obj = objv[word];
- cfwPtr->pc = pc;
- cfwPtr->word = word;
- cfwPtr->nextPtr = lastPtr;
- lastPtr = cfwPtr;
-
- if (isnew) {
- /*
- * The word is not on the stack yet, remember the current
- * location and initialize references.
- */
-
- cfwPtr->prevPtr = NULL;
- } else {
- /*
- * The object is already on the stack, however it may have
- * a different location now (literal sharing may map
- * multiple location to a single Tcl_Obj*. Save the old
- * information in the new structure.
- */
-
- cfwPtr->prevPtr = Tcl_GetHashValue(hPtr);
- }
-
- Tcl_SetHashValue(hPtr, cfwPtr);
- }
- } /* for */
-
- cfPtr->litarg = lastPtr;
- } /* if */
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclArgumentBCRelease --
- *
- * This procedure is a helper for the TIP #280 uplevel extension. It
- * removes the location references for the literal arguments of commands
- * in bytecode just done. Usage is counted down, the data is removed only
- * when no user is left over.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May release memory.
- *
- * TIP #280
- *----------------------------------------------------------------------
- */
-
-void
-TclArgumentBCRelease(
- Tcl_Interp *interp,
- CmdFrame *cfPtr)
-{
- Interp *iPtr = (Interp *) interp;
- CFWordBC *cfwPtr = (CFWordBC *) cfPtr->litarg;
-
- while (cfwPtr) {
- CFWordBC *nextPtr = cfwPtr->nextPtr;
- Tcl_HashEntry *hPtr =
- Tcl_FindHashEntry(iPtr->lineLABCPtr, (char *) cfwPtr->obj);
- CFWordBC *xPtr = Tcl_GetHashValue(hPtr);
-
- if (xPtr != cfwPtr) {
- Tcl_Panic("TclArgumentBC Enter/Release Mismatch");
- }
-
- if (cfwPtr->prevPtr) {
- Tcl_SetHashValue(hPtr, cfwPtr->prevPtr);
- } else {
- Tcl_DeleteHashEntry(hPtr);
- }
-
- ckfree(cfwPtr);
- cfwPtr = nextPtr;
- }
-
- cfPtr->litarg = NULL;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclArgumentGet --
- *
- * This procedure is a helper for the TIP #280 uplevel extension. It
- * finds the location references for a Tcl_Obj, if any.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Writes found location information into the result arguments.
- *
- * TIP #280
- *----------------------------------------------------------------------
- */
-
-void
-TclArgumentGet(
- Tcl_Interp *interp,
- Tcl_Obj *obj,
- CmdFrame **cfPtrPtr,
- int *wordPtr)
-{
- Interp *iPtr = (Interp *) interp;
- Tcl_HashEntry *hPtr;
- CmdFrame *framePtr;
-
- /*
- * An object which either has no string rep or else is a canonical list is
- * guaranteed to have been generated dynamically: bail out, this cannot
- * have a usable absolute location. _Do not touch_ the information the set
- * up by the caller. It knows better than us.
- */
-
- if ((obj->bytes == NULL) || TclListObjIsCanonical(obj)) {
- return;
- }
-
- /*
- * First look for location information recorded in the argument
- * stack. That is nearest.
- */
-
- hPtr = Tcl_FindHashEntry(iPtr->lineLAPtr, (char *) obj);
- if (hPtr) {
- CFWord *cfwPtr = Tcl_GetHashValue(hPtr);
-
- *wordPtr = cfwPtr->word;
- *cfPtrPtr = cfwPtr->framePtr;
- return;
- }
-
- /*
- * Check if the Tcl_Obj has location information as a bytecode literal, in
- * that stack.
- */
-
- hPtr = Tcl_FindHashEntry(iPtr->lineLABCPtr, (char *) obj);
- if (hPtr) {
- CFWordBC *cfwPtr = Tcl_GetHashValue(hPtr);
-
- framePtr = cfwPtr->framePtr;
- framePtr->data.tebc.pc = (char *) (((ByteCode *)
- framePtr->data.tebc.codePtr)->codeStart + cfwPtr->pc);
- *cfPtrPtr = cfwPtr->framePtr;
- *wordPtr = cfwPtr->word;
- return;
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
* Tcl_Eval --
*
* Execute a Tcl command in a string. This function executes the script
@@ -5883,7 +5137,6 @@ Tcl_GlobalEvalObj(
* the bytecode instructions for the commands. Executing the commands
* will almost certainly have side effects that depend on those commands.
*
- * TIP #280 : Keep public API, internally extended API.
*----------------------------------------------------------------------
*/
@@ -5897,25 +5150,10 @@ Tcl_EvalObjEx(
* evaluation of the script. Supported values
* are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */
{
- return TclEvalObjEx(interp, objPtr, flags, NULL, 0);
-}
-
-int
-TclEvalObjEx(
- Tcl_Interp *interp, /* Token for command interpreter (returned by
- * a previous call to Tcl_CreateInterp). */
- register Tcl_Obj *objPtr, /* Pointer to object containing commands to
- * execute. */
- int flags, /* Collection of OR-ed bits that control the
- * evaluation of the script. Supported values
- * are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */
- const CmdFrame *invoker, /* Frame of the command doing the eval. */
- int word) /* Index of the word which is in objPtr. */
-{
int result = TCL_OK;
NRE_callback *rootPtr = TOP_CB(interp);
- result = TclNREvalObjEx(interp, objPtr, flags, invoker, word);
+ result = TclNREvalObjEx(interp, objPtr, flags);
return TclNRRunCallbacks(interp, result, rootPtr);
}
@@ -5925,11 +5163,9 @@ TclNREvalObjEx(
* a previous call to Tcl_CreateInterp). */
register Tcl_Obj *objPtr, /* Pointer to object containing commands to
* execute. */
- int flags, /* Collection of OR-ed bits that control the
+ int flags) /* Collection of OR-ed bits that control the
* evaluation of the script. Supported values
* are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */
- const CmdFrame *invoker, /* Frame of the command doing the eval. */
- int word) /* Index of the word which is in objPtr. */
{
Interp *iPtr = (Interp *) interp;
int result;
@@ -5942,7 +5178,6 @@ TclNREvalObjEx(
if (TclListObjIsCanonical(objPtr)) {
Tcl_Obj *listPtr = objPtr;
- CmdFrame *eoFramePtr = NULL;
int objc;
Tcl_Obj **objv;
@@ -5976,42 +5211,8 @@ TclNREvalObjEx(
Tcl_IncrRefCount(listPtr);
TclDecrRefCount(objPtr);
- if (word != INT_MIN) {
- /*
- * TIP #280 Structures for tracking lines. As we know that this is
- * dynamic execution we ignore the invoker, even if known.
- *
- * TIP #280. We do _not_ compute all the line numbers for the
- * words in the command. For the eval of a pure list the most
- * sensible choice is to put all words on line 1. Given that we
- * neither need memory for them nor compute anything. 'line' is
- * left NULL. The two places using this information (TclInfoFrame,
- * and TclInitCompileEnv), are special-cased to use the proper
- * line number directly instead of accessing the 'line' array.
- *
- * Note that we use (word==INTMIN) to signal that no command frame
- * should be pushed, as needed by alias and ensemble redirections.
- */
-
- eoFramePtr = TclStackAlloc(interp, sizeof(CmdFrame));
- eoFramePtr->nline = 0;
- eoFramePtr->line = NULL;
-
- eoFramePtr->type = TCL_LOCATION_EVAL_LIST;
- eoFramePtr->level = (iPtr->cmdFramePtr == NULL?
- 1 : iPtr->cmdFramePtr->level + 1);
- eoFramePtr->numLevels = iPtr->numLevels;
- eoFramePtr->framePtr = iPtr->framePtr;
- eoFramePtr->nextPtr = iPtr->cmdFramePtr;
-
- eoFramePtr->cmd.listPtr = listPtr;
- eoFramePtr->data.eval.path = NULL;
-
- iPtr->cmdFramePtr = eoFramePtr;
- }
-
TclMarkTailcall(interp);
- TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr,
+ TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, NULL,
NULL, NULL);
ListObjGetElements(listPtr, objc, objv);
@@ -6021,9 +5222,6 @@ TclNREvalObjEx(
if (!(flags & TCL_EVAL_DIRECT)) {
/*
* Let the compiler/engine subsystem do the evaluation.
- *
- * TIP #280 The invoker provides us with the context for the script.
- * We transfer this to the byte code compiler.
*/
int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
@@ -6040,7 +5238,7 @@ TclNREvalObjEx(
iPtr->varFramePtr = iPtr->rootFramePtr;
}
Tcl_IncrRefCount(objPtr);
- codePtr = TclCompileObj(interp, objPtr, invoker, word);
+ codePtr = TclCompileObj(interp, objPtr);
TclNRAddCallback(interp, TEOEx_ByteCodeCallback, savedVarFramePtr,
objPtr, INT2PTR(allowExceptions), NULL);
@@ -6053,121 +5251,14 @@ TclNREvalObjEx(
* interpreter. Let Tcl_EvalEx evaluate the command directly (and
* probably more slowly).
*
- * TIP #280. Propagate context as much as we can. Especially if the
- * script to evaluate is a single literal it makes sense to look if
- * our context is one with absolute line numbers we can then track
- * into the literal itself too.
- *
- * See also tclCompile.c, TclInitCompileEnv, for the equivalent code
- * in the bytecode compiler.
*/
const char *script;
int numSrcBytes;
- /*
- * Now we check if we have data about invisible continuation lines for
- * the script, and make it available to the direct script parser and
- * evaluator we are about to call, if so.
- *
- * It may be possible that the script Tcl_Obj* can be free'd while the
- * evaluator is using it, leading to the release of the associated
- * ContLineLoc structure as well. To ensure that the latter doesn't
- * happen we set a lock on it. We release this lock later in this
- * function, after the evaluator is done. The relevant "lineCLPtr"
- * hashtable is managed in the file "tclObj.c".
- *
- * Another important action is to save (and later restore) the
- * continuation line information of the caller, in case we are
- * executing nested commands in the eval/direct path.
- */
-
- ContLineLoc *saveCLLocPtr = iPtr->scriptCLLocPtr;
- ContLineLoc *clLocPtr = TclContinuationsGet(objPtr);
-
- if (clLocPtr) {
- iPtr->scriptCLLocPtr = clLocPtr;
- Tcl_Preserve(iPtr->scriptCLLocPtr);
- } else {
- iPtr->scriptCLLocPtr = NULL;
- }
-
Tcl_IncrRefCount(objPtr);
- if (invoker == NULL) {
- /*
- * No context, force opening of our own.
- */
-
- script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
- result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
- } else {
- /*
- * We have an invoker, describing the command asking for the
- * evaluation of a subordinate script. This script may originate
- * in a literal word, or from a variable, etc. Using the line
- * array we now check if we have good line information for the
- * relevant word. The type of context is relevant as well. In a
- * non-'source' context we don't have to try tracking lines.
- *
- * First see if the word exists and is a literal. If not we go
- * through the easy dynamic branch. No need to perform more
- * complex invokations.
- */
-
- int pc = 0;
- CmdFrame *ctxPtr = TclStackAlloc(interp, sizeof(CmdFrame));
-
- *ctxPtr = *invoker;
- if (invoker->type == TCL_LOCATION_BC) {
- /*
- * Note: Type BC => ctxPtr->data.eval.path is not used.
- * ctxPtr->data.tebc.codePtr is used instead.
- */
-
- TclGetSrcInfoForPc(ctxPtr);
- pc = 1;
- }
-
- script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
-
- if ((invoker->nline <= word) ||
- (invoker->line[word] < 0) ||
- (ctxPtr->type != TCL_LOCATION_SOURCE)) {
- /*
- * Dynamic script, or dynamic context, force our own context.
- */
-
- result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
- } else {
- /*
- * Absolute context to reuse.
- */
-
- iPtr->invokeCmdFramePtr = ctxPtr;
- iPtr->evalFlags |= TCL_EVAL_CTX;
-
- result = TclEvalEx(interp, script, numSrcBytes, flags,
- ctxPtr->line[word], NULL, script);
- }
- if (pc && (ctxPtr->type == TCL_LOCATION_SOURCE)) {
- /*
- * Death of SrcInfo reference.
- */
-
- Tcl_DecrRefCount(ctxPtr->data.eval.path);
- }
- TclStackFree(interp, ctxPtr);
- }
-
- /*
- * Now release the lock on the continuation line information, if any,
- * and restore the caller's settings.
- */
-
- if (iPtr->scriptCLLocPtr) {
- Tcl_Release(iPtr->scriptCLLocPtr);
- }
- iPtr->scriptCLLocPtr = saveCLLocPtr;
+ script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
+ result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
TclDecrRefCount(objPtr);
return result;
}
@@ -6225,20 +5316,9 @@ TEOEx_ListCallback(
Tcl_Interp *interp,
int result)
{
- Interp *iPtr = (Interp *) interp;
Tcl_Obj *listPtr = data[0];
- CmdFrame *eoFramePtr = data[1];
-
- /*
- * Remove the cmdFrame
- */
- if (eoFramePtr) {
- iPtr->cmdFramePtr = eoFramePtr->nextPtr;
- TclStackFree(interp, eoFramePtr);
- }
TclDecrRefCount(listPtr);
-
return result;
}
@@ -7995,65 +7075,6 @@ DTraceObjCmd(
/*
*----------------------------------------------------------------------
*
- * TclDTraceInfo --
- *
- * Extract information from a TIP280 dict for use by DTrace probes.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TclDTraceInfo(
- Tcl_Obj *info,
- const char **args,
- int *argsi)
-{
- static Tcl_Obj *keys[10] = { NULL };
- Tcl_Obj **k = keys, *val;
- int i = 0;
-
- if (!*k) {
-#define kini(s) TclNewLiteralStringObj(keys[i], s); i++
- kini("cmd"); kini("type"); kini("proc"); kini("file");
- kini("method"); kini("class"); kini("lambda"); kini("object");
- kini("line"); kini("level");
-#undef kini
- }
- for (i = 0; i < 6; i++) {
- Tcl_DictObjGet(NULL, info, *k++, &val);
- args[i] = val ? TclGetString(val) : NULL;
- }
- /* no "proc" -> use "lambda" */
- if (!args[2]) {
- Tcl_DictObjGet(NULL, info, *k, &val);
- args[2] = val ? TclGetString(val) : NULL;
- }
- k++;
- /* no "class" -> use "object" */
- if (!args[5]) {
- Tcl_DictObjGet(NULL, info, *k, &val);
- args[5] = val ? TclGetString(val) : NULL;
- }
- k++;
- for (i = 0; i < 2; i++) {
- Tcl_DictObjGet(NULL, info, *k++, &val);
- if (val) {
- TclGetIntFromObj(NULL, val, &argsi[i]);
- } else {
- argsi[i] = 0;
- }
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
* DTraceCmdReturn --
*
* NR callback for DTrace command return probes.
@@ -8132,14 +7153,6 @@ Tcl_NRCallObjProc(
TCL_DTRACE_CMD_ARGS(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
a[8], a[9]);
}
- if (TCL_DTRACE_CMD_INFO_ENABLED() && ((Interp *) interp)->cmdFramePtr) {
- Tcl_Obj *info = TclInfoFrame(interp, ((Interp *) interp)->cmdFramePtr);
- const char *a[6]; int i[2];
-
- TclDTraceInfo(info, a, i);
- TCL_DTRACE_CMD_INFO(a[0], a[1], a[2], a[3], i[0], i[1], a[4], a[5]);
- TclDecrRefCount(info);
- }
if ((TCL_DTRACE_CMD_RETURN_ENABLED() || TCL_DTRACE_CMD_RESULT_ENABLED())
&& objc) {
TclNRAddCallback(interp, DTraceCmdReturn, objv[0], NULL, NULL, NULL);
@@ -8217,7 +7230,7 @@ Tcl_NREvalObj(
Tcl_Obj *objPtr,
int flags)
{
- return TclNREvalObjEx(interp, objPtr, flags, NULL, INT_MIN);
+ return TclNREvalObjEx(interp, objPtr, flags);
}
int
@@ -8626,7 +7639,6 @@ NRCoroutineCallerCallback(
NRE_ASSERT(iPtr->varFramePtr == corPtr->caller.varFramePtr);
NRE_ASSERT(iPtr->framePtr == corPtr->caller.framePtr);
- NRE_ASSERT(iPtr->cmdFramePtr == corPtr->caller.cmdFramePtr);
ckfree(corPtr);
return result;
}
@@ -8679,16 +7691,6 @@ NRCoroutineExitCallback(
corPtr->stackLevel = NULL;
- /*
- * #280.
- * Drop the coroutine-owned copy of the lineLABCPtr hashtable for literal
- * command arguments in bytecode.
- */
-
- Tcl_DeleteHashTable(corPtr->lineLABCPtr);
- ckfree(corPtr->lineLABCPtr);
- corPtr->lineLABCPtr = NULL;
-
RESTORE_CONTEXT(corPtr->caller);
iPtr->execEnvPtr = corPtr->callerEEPtr;
iPtr->numLevels++;
@@ -8835,7 +7837,7 @@ NRCoroInjectObjCmd(
*/
iPtr->execEnvPtr = corPtr->eePtr;
- TclNREvalObjEx(interp, Tcl_NewListObj(objc-2, objv+2), 0, NULL, INT_MIN);
+ TclNREvalObjEx(interp, Tcl_NewListObj(objc-2, objv+2), 0);
iPtr->execEnvPtr = savedEEPtr;
return TCL_OK;
@@ -8978,41 +7980,11 @@ TclNRCoroutineObjCmd(
cmdPtr->refCount++;
/*
- * #280.
- * Provide the new coroutine with its own copy of the lineLABCPtr
- * hashtable for literal command arguments in bytecode. Note that that
- * CFWordBC chains are not duplicated, only the entrypoints to them. This
- * means that in the presence of coroutines each chain is potentially a
- * tree. Like the chain -> tree conversion of the CmdFrame stack.
- */
-
- {
- Tcl_HashSearch hSearch;
- Tcl_HashEntry *hePtr;
-
- corPtr->lineLABCPtr = ckalloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(corPtr->lineLABCPtr, TCL_ONE_WORD_KEYS);
-
- for (hePtr = Tcl_FirstHashEntry(iPtr->lineLABCPtr,&hSearch);
- hePtr; hePtr = Tcl_NextHashEntry(&hSearch)) {
- int isNew;
- Tcl_HashEntry *newPtr =
- Tcl_CreateHashEntry(corPtr->lineLABCPtr,
- Tcl_GetHashKey(iPtr->lineLABCPtr, hePtr),
- &isNew);
-
- Tcl_SetHashValue(newPtr, Tcl_GetHashValue(hePtr));
- }
- }
-
- /*
* Create the base context.
*/
corPtr->running.framePtr = iPtr->rootFramePtr;
corPtr->running.varFramePtr = iPtr->rootFramePtr;
- corPtr->running.cmdFramePtr = NULL;
- corPtr->running.lineLABCPtr = corPtr->lineLABCPtr;
corPtr->stackLevel = NULL;
corPtr->auxNumLevels = 0;