diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2016-01-14 03:46:54 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2016-01-14 03:46:54 (GMT) |
commit | 4663c81f00c6c920081f7b163414f4294f02fd78 (patch) | |
tree | 4fc7bd19d145c805cb0d43506b91e3fefadad792 | |
parent | ffc1d2a8ba79e51264d9056314c8b23294a44443 (diff) | |
parent | 33224a792fa313b8c2214d750d709b765ccce70f (diff) | |
download | tcl-4663c81f00c6c920081f7b163414f4294f02fd78.zip tcl-4663c81f00c6c920081f7b163414f4294f02fd78.tar.gz tcl-4663c81f00c6c920081f7b163414f4294f02fd78.tar.bz2 |
remove tips #280 and #348
50 files changed, 867 insertions, 6492 deletions
@@ -2,11 +2,6 @@ **** TODO *************************************************************** ************************************************************************* -* remove [info frame] and [info errortsack], as well as all supporting - code. These should be recoded using the data that NRE is - keeping. Anything additional should ALWAYS choose to recompute on demand - over precomputing things during normal operation - * bring up relevant mods (if any) from mig-alloc-reform @@ -46,4 +41,9 @@ * remove interp->result and all supporting code; remove other deprecated apis +* remove [info frame] and [info errortsack], as well as all supporting + code. These should be recoded using the data that NRE is + keeping. Anything additional should ALWAYS choose to recompute on demand + over precomputing things during normal operation + diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 0f7a794..b73aeac 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -80,15 +80,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: @@ -148,6 +144,8 @@ static int TEOV_NotFound(Tcl_Interp *interp, int objc, static int TEOV_RunEnterTraces(Tcl_Interp *interp, Command **cmdPtrPtr, Tcl_Obj *commandPtr, int objc, Tcl_Obj *const objv[]); +static Tcl_Obj * GetCommandSource(Interp *iPtr, int objc, + Tcl_Obj *const objv[]); static Tcl_NRPostProc RewindCoroutineCallback; static Tcl_NRPostProc TailcallCleanup; static Tcl_NRPostProc TEOEx_ByteCodeCallback; @@ -400,6 +398,31 @@ static const OpCmdInfo mathOpCmds[] = { { NULL, NULL, NULL, {0}, NULL} }; + +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; + } +} /* *---------------------------------------------------------------------- @@ -526,39 +549,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); @@ -1347,7 +1343,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); } @@ -1541,90 +1530,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); - } - - 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. */ @@ -3350,6 +3255,70 @@ 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. 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. + * + *---------------------------------------------------------------------- + */ + +static Tcl_Obj * +GetCommandSource( + Interp *iPtr, + int objc, + Tcl_Obj *const objv[]) +{ + Tcl_Obj *objPtr = Tcl_NewListObj(objc, objv); + NRE_callback *runPtr; + Tcl_Obj *cmdSourcePtr; + + + /* Find the NRCommand in the NRE stack, get the cmdSourcePtr */ + for (runPtr = TOP_CB(iPtr); runPtr; runPtr = NEXT_CB(runPtr)) { + if (((runPtr->procPtr) == NRCommand) && !runPtr->data[1]) { + break; + } + } + if (!runPtr) { + Tcl_Panic("GetCommandSource cannot find the NRcommand: should not happen!"); + } + cmdSourcePtr = (Tcl_Obj *) (runPtr->data[0]); + + if (cmdSourcePtr) { + char *command; + int len; + char *orig = cmdSourcePtr->bytes; + + command = Tcl_GetStringFromObj(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(cmdSourcePtr); + } + } + Tcl_IncrRefCount(objPtr); + return objPtr; +} + +/* + *---------------------------------------------------------------------- + * * TclCleanupCommand -- * * This function frees up a Command structure unless it is still @@ -4124,9 +4093,15 @@ TclNREvalObjv( if (iPtr->deferredCallbacks) { iPtr->deferredCallbacks = NULL; + } else if (iPtr->cmdSourcePtr) { + TclNRAddCallback(interp, NRCommand, iPtr->cmdSourcePtr, + NULL, NULL, NULL); + iPtr->cmdSourcePtr = NULL; } else { - TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL); + TclNRAddCallback(interp, NRCommand, NULL, + NULL, NULL, NULL); } + iPtr->numLevels++; TclNRAddCallback(interp, EvalObjvCore, cmdPtr, INT2PTR(flags), @@ -4231,11 +4206,10 @@ EvalObjvCore( if (enterTracesDone || iPtr->tracePtr || (cmdPtr->flags & CMD_HAS_EXEC_TRACES)) { - Tcl_Obj *commandPtr = TclGetSourceFromFrame( - flags & TCL_EVAL_SOURCE_IN_FRAME ? iPtr->cmdFramePtr : NULL, - objc, objv); - Tcl_IncrRefCount(commandPtr); - + Tcl_Obj *commandPtr = (flags & TCL_EVAL_SOURCE_IN_FRAME) + ? GetCommandSource(iPtr, objc, objv) + : Tcl_NewListObj(objc, objv); + if (!enterTracesDone) { int code = TEOV_RunEnterTraces(interp, &cmdPtr, commandPtr, @@ -4291,14 +4265,6 @@ EvalObjvCore( 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()) && objc) { TclNRAddCallback(interp, DTraceCmdReturn, objv[0], NULL, NULL, NULL); @@ -4371,10 +4337,10 @@ NRCommand( int result) { Interp *iPtr = (Interp *) interp; - + iPtr->numLevels--; - /* + /* * If there is a tailcall, schedule it next */ @@ -4807,8 +4773,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); } /* @@ -4892,44 +4857,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 @@ -4942,28 +4874,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); @@ -4981,36 +4894,15 @@ 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 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->framePtr = iPtr->framePtr; - eeFramePtr->nextPtr = iPtr->cmdFramePtr; - eeFramePtr->nline = 0; - eeFramePtr->line = NULL; - eeFramePtr->cmdObj = NULL; - - iPtr->cmdFramePtr = eeFramePtr; 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 @@ -5029,18 +4921,7 @@ TclEvalEx( 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; @@ -5052,28 +4933,8 @@ TclEvalEx( goto posterror; } - /* - * 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; @@ -5084,39 +4945,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; @@ -5148,13 +4985,7 @@ TclEvalEx( expand[objectsUsed] = 0; objectsNeeded++; } - - if (wordCLNext) { - TclContinuationsEnterDerived(objv[objectsUsed], - wordStart - outerScript, wordCLNext); - } } /* for loop */ - iPtr->cmdFramePtr = eeFramePtr; if (code != TCL_OK) { goto error; } @@ -5164,14 +4995,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; @@ -5184,13 +5013,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++; } @@ -5200,44 +5027,26 @@ 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. + * Execute the command. */ - eeFramePtr->cmd = parsePtr->commandStart; - eeFramePtr->len = parsePtr->commandSize; - - if (parsePtr->term == - parsePtr->commandStart + parsePtr->commandSize - 1) { - eeFramePtr->len--; - } - - eeFramePtr->nline = objectsUsed; - eeFramePtr->line = lines; - - TclArgumentEnter(interp, objv, objectsUsed, eeFramePtr); - code = Tcl_EvalObjv(interp, objectsUsed, objv, - TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME); - TclArgumentRelease(interp, objv, objectsUsed); - - eeFramePtr->line = NULL; - eeFramePtr->nline = 0; - if (eeFramePtr->cmdObj) { - Tcl_DecrRefCount(eeFramePtr->cmdObj); - eeFramePtr->cmdObj = NULL; - } - + { + Tcl_Obj *tmp = Tcl_NewObj(); + TclInvalidateStringRep(tmp); + tmp->typePtr = &scriptSourceType; + tmp->internalRep.twoPtrValue.ptr1 = (char *) script; + tmp->internalRep.twoPtrValue.ptr2 = INT2PTR(numBytes); + iPtr->cmdSourcePtr = tmp; + + Tcl_IncrRefCount(tmp); + code = Tcl_EvalObjv(interp, objectsUsed, objv, + TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME); + Tcl_DecrRefCount(tmp); + } + if (code != TCL_OK) { goto error; } @@ -5248,8 +5057,6 @@ TclEvalEx( if (objvSpace != stackObjArray) { ckfree(objvSpace); objvSpace = stackObjArray; - ckfree(lineSpace); - lineSpace = linesStack; } /* @@ -5266,14 +5073,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); @@ -5325,7 +5129,6 @@ TclEvalEx( } if (objvSpace != stackObjArray) { ckfree(objvSpace); - ckfree(lineSpace); } if (expand != expandStack) { ckfree(expand); @@ -5333,18 +5136,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; @@ -5353,448 +5146,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 cmd, - int pc) -{ - ExtCmdLoc *eclPtr; - int word; - ECL *ePtr; - CFWordBC *lastPtr = NULL; - Interp *iPtr = (Interp *) interp; - Tcl_HashEntry *hePtr = - Tcl_FindHashEntry(iPtr->lineBCPtr, (char *) codePtr); - - if (!hePtr) { - return; - } - eclPtr = Tcl_GetHashValue(hePtr); - ePtr = &eclPtr->loc[cmd]; - - /* - * ePtr->nline is the number of words originally parsed. - * - * objc is the number of elements getting invoked. - * - * If they are not the same, we arrived here by compiling an - * ensemble dispatch. Ensemble subcommands that lead to script - * evaluation are not supposed to get compiled, because a command - * such as [info level] in the script can expose some of the dispatch - * shenanigans. This means that we don't have to tend to the - * housekeeping, and can escape now. - */ - - if (ePtr->nline != objc) { - return; - } - - /* - * Having disposed of the ensemble cases, we can state... - * 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. - */ - - 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; -} - -/* - *---------------------------------------------------------------------- - * - * 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 @@ -5876,11 +5227,6 @@ Tcl_GlobalEvalObj( * compiled into bytecodes if necessary, unless TCL_EVAL_DIRECT is * specified. * - * If the flag TCL_EVAL_DIRECT is passed in, the value of invoker - * must be NULL. Support for non-NULL invokers in that mode has - * been removed since it was unused and untested. Failure to - * follow this limitation will lead to an assertion panic. - * * Results: * The return value is one of the return codes defined in tcl.h (such as * TCL_OK), and the interpreter's result contains a value to supplement @@ -5891,7 +5237,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. *---------------------------------------------------------------------- */ @@ -5905,25 +5250,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; TclNRSetRoot(interp); - result = TclNREvalObjEx(interp, objPtr, flags, invoker, word); + result = TclNREvalObjEx(interp, objPtr, flags); return TclNRRunCallbacks(interp, result); } @@ -5933,11 +5263,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; @@ -5949,7 +5277,6 @@ TclNREvalObjEx( */ if (TclListObjIsCanonical(objPtr)) { - CmdFrame *eoFramePtr = NULL; int objc; Tcl_Obj *listPtr, **objv; @@ -5978,46 +5305,8 @@ TclNREvalObjEx( listPtr = TclListObjCopy(interp, objPtr); Tcl_IncrRefCount(listPtr); - 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; - eoFramePtr->level = (iPtr->cmdFramePtr == NULL? - 1 : iPtr->cmdFramePtr->level + 1); - eoFramePtr->framePtr = iPtr->framePtr; - eoFramePtr->nextPtr = iPtr->cmdFramePtr; - - eoFramePtr->cmdObj = objPtr; - eoFramePtr->cmd = NULL; - eoFramePtr->len = 0; - eoFramePtr->data.eval.path = NULL; - - iPtr->cmdFramePtr = eoFramePtr; - - flags |= TCL_EVAL_SOURCE_IN_FRAME; - } - TclMarkTailcall(interp); - TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr, - objPtr, NULL); + TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, objPtr, NULL, NULL); ListObjGetElements(listPtr, objc, objv); return TclNREvalObjv(interp, objc, objv, flags, NULL); @@ -6027,8 +5316,6 @@ TclNREvalObjEx( /* * 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); @@ -6045,7 +5332,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); @@ -6062,37 +5349,12 @@ TclNREvalObjEx( 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; - - assert(invoker == NULL); - - iPtr->scriptCLLocPtr = TclContinuationsGet(objPtr); - Tcl_IncrRefCount(objPtr); script = Tcl_GetStringFromObj(objPtr, &numSrcBytes); result = Tcl_EvalEx(interp, script, numSrcBytes, flags); TclDecrRefCount(objPtr); - - iPtr->scriptCLLocPtr = saveCLLocPtr; return result; } } @@ -6149,22 +5411,11 @@ TEOEx_ListCallback( Tcl_Interp *interp, int result) { - Interp *iPtr = (Interp *) interp; Tcl_Obj *listPtr = data[0]; - CmdFrame *eoFramePtr = data[1]; - Tcl_Obj *objPtr = data[2]; - - /* - * Remove the cmdFrame - */ + Tcl_Obj *objPtr = data[1]; - if (eoFramePtr) { - iPtr->cmdFramePtr = eoFramePtr->nextPtr; - TclStackFree(interp, eoFramePtr); - } TclDecrRefCount(objPtr); TclDecrRefCount(listPtr); - return result; } @@ -8090,7 +7341,7 @@ Tcl_NREvalObj( Tcl_Obj *objPtr, int flags) { - return TclNREvalObjEx(interp, objPtr, flags, NULL, INT_MIN); + return TclNREvalObjEx(interp, objPtr, flags); } int @@ -8531,7 +7782,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; } @@ -8589,16 +7839,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++; @@ -8745,7 +7985,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; @@ -8888,41 +8128,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; diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index ec8ea5f..f6d48f9 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -166,7 +166,6 @@ TclNRCatchObjCmd( { Tcl_Obj *varNamePtr = NULL; Tcl_Obj *optionVarNamePtr = NULL; - Interp *iPtr = (Interp *) interp; if ((objc < 2) || (objc > 4)) { Tcl_WrongNumArgs(interp, 1, objv, @@ -183,12 +182,7 @@ TclNRCatchObjCmd( TclNRAddCallback(interp, CatchObjCmdCallback, INT2PTR(objc), varNamePtr, optionVarNamePtr, NULL); - - /* - * TIP #280. Make invoking context available to caught script. - */ - - return TclNREvalObjEx(interp, objv[1], 0, iPtr->cmdFramePtr, 1); + return TclNREvalObjEx(interp, objv[1], 0); } static int @@ -623,9 +617,6 @@ TclNREvalObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { register Tcl_Obj *objPtr; - Interp *iPtr = (Interp *) interp; - CmdFrame *invoker = NULL; - int word = 0; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?"); @@ -633,28 +624,18 @@ TclNREvalObjCmd( } if (objc == 2) { - /* - * TIP #280. Make argument location available to eval'd script. - */ - - invoker = iPtr->cmdFramePtr; - word = 1; objPtr = objv[1]; - TclArgumentGet(interp, objPtr, &invoker, &word); } else { /* * More than one argument: concatenate them together with spaces * between, then evaluate the result. Tcl_EvalObjEx will delete the * object when it decrements its refcount after eval'ing it. - * - * TIP #280. Make invoking context available to eval'd script, done - * with the default values. */ objPtr = Tcl_ConcatObj(objc-1, objv+1); } TclNRAddCallback(interp, EvalCmdErrMsg, NULL, NULL, NULL, NULL); - return TclNREvalObjEx(interp, objPtr, 0, invoker, word); + return TclNREvalObjEx(interp, objPtr, 0); } /* @@ -2271,28 +2252,14 @@ TclNRForObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Interp *iPtr = (Interp *) interp; - ForIterData *iterPtr; - if (objc != 5) { Tcl_WrongNumArgs(interp, 1, objv, "start test next command"); return TCL_ERROR; } - TclSmallAllocEx(interp, sizeof(ForIterData), iterPtr); - iterPtr->cond = objv[2]; - iterPtr->body = objv[4]; - iterPtr->next = objv[3]; - iterPtr->msg = "\n (\"for\" body line %d)"; - iterPtr->word = 4; - - TclNRAddCallback(interp, ForSetupCallback, iterPtr, NULL, NULL, NULL); - - /* - * TIP #280. Make invoking context available to initial script. - */ - - return TclNREvalObjEx(interp, objv[1], 0, iPtr->cmdFramePtr, 1); + TclNRAddCallback(interp, ForSetupCallback, /*cond*/ objv[2], + /*body*/ objv[4], /*next*/ objv[3], NULL); + return TclNREvalObjEx(interp, objv[1], 0); } static int @@ -2301,16 +2268,14 @@ ForSetupCallback( Tcl_Interp *interp, int result) { - ForIterData *iterPtr = data[0]; - if (result != TCL_OK) { if (result == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\n (\"for\" initial command)"); } - TclSmallFreeEx(interp, iterPtr); return result; } - TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL, NULL, NULL); + TclNRAddCallback(interp, TclNRForIterCallback, data[0], data[1], data[2], + data[3]); return TCL_OK; } @@ -2320,7 +2285,6 @@ TclNRForIterCallback( Tcl_Interp *interp, int result) { - ForIterData *iterPtr = data[0]; Tcl_Obj *boolObj; switch (result) { @@ -2334,18 +2298,17 @@ TclNRForIterCallback( Tcl_ResetResult(interp); TclNewObj(boolObj); - TclNRAddCallback(interp, ForCondCallback, iterPtr, boolObj, NULL, - NULL); - return Tcl_NRExprObj(interp, iterPtr->cond, boolObj); + TclNRAddCallback(interp, ForCondCallback, data[0], data[1], data[2], + boolObj); + return Tcl_NRExprObj(interp, /*cond*/ data[0], boolObj); case TCL_BREAK: result = TCL_OK; Tcl_ResetResult(interp); break; case TCL_ERROR: - Tcl_AppendObjToErrorInfo(interp, - Tcl_ObjPrintf(iterPtr->msg, Tcl_GetErrorLine(interp))); + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (loop body line %d)", Tcl_GetErrorLine(interp))); } - TclSmallFreeEx(interp, iterPtr); return result; } @@ -2355,35 +2318,28 @@ ForCondCallback( Tcl_Interp *interp, int result) { - Interp *iPtr = (Interp *) interp; - ForIterData *iterPtr = data[0]; - Tcl_Obj *boolObj = data[1]; + Tcl_Obj *boolObj = data[3]; int value; if (result != TCL_OK) { Tcl_DecrRefCount(boolObj); - TclSmallFreeEx(interp, iterPtr); return result; } else if (Tcl_GetBooleanFromObj(interp, boolObj, &value) != TCL_OK) { Tcl_DecrRefCount(boolObj); - TclSmallFreeEx(interp, iterPtr); return TCL_ERROR; } Tcl_DecrRefCount(boolObj); if (value) { - /* TIP #280. */ - if (iterPtr->next) { - TclNRAddCallback(interp, ForNextCallback, iterPtr, NULL, NULL, - NULL); + if (/*next*/ data[2]) { + TclNRAddCallback(interp, ForNextCallback, data[0], data[1], + data[2], NULL); } else { - TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL, - NULL, NULL); + TclNRAddCallback(interp, TclNRForIterCallback, data[0], data[1], + data[2], NULL); } - return TclNREvalObjEx(interp, iterPtr->body, 0, iPtr->cmdFramePtr, - iterPtr->word); + return TclNREvalObjEx(interp, /*body*/ data[1], 0); } - TclSmallFreeEx(interp, iterPtr); return result; } @@ -2393,22 +2349,16 @@ ForNextCallback( Tcl_Interp *interp, int result) { - Interp *iPtr = (Interp *) interp; - ForIterData *iterPtr = data[0]; - Tcl_Obj *next = iterPtr->next; + Tcl_Obj *next = /*body*/ data[2]; if ((result == TCL_OK) || (result == TCL_CONTINUE)) { - TclNRAddCallback(interp, ForPostNextCallback, iterPtr, NULL, NULL, - NULL); - - /* - * TIP #280. Make invoking context available to next script. - */ - - return TclNREvalObjEx(interp, next, 0, iPtr->cmdFramePtr, 3); + TclNRAddCallback(interp, ForPostNextCallback, data[0], data[1], + data[2], NULL); + return TclNREvalObjEx(interp, next, 0); } - TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL, NULL, NULL); + TclNRAddCallback(interp, TclNRForIterCallback, data[0], data[1], + data[2], NULL); return result; } @@ -2418,16 +2368,14 @@ ForPostNextCallback( Tcl_Interp *interp, int result) { - ForIterData *iterPtr = data[0]; - if ((result != TCL_BREAK) && (result != TCL_OK)) { if (result == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\n (\"for\" loop-end command)"); - TclSmallFreeEx(interp, iterPtr); } return result; } - TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL, NULL, NULL); + TclNRAddCallback(interp, TclNRForIterCallback, data[0], data[1], + data[2], NULL); return result; } @@ -2599,8 +2547,7 @@ EachloopCmd( } TclNRAddCallback(interp, ForeachLoopStep, statePtr, NULL, NULL, NULL); - return TclNREvalObjEx(interp, objv[objc-1], 0, - ((Interp *) interp)->cmdFramePtr, objc-1); + return TclNREvalObjEx(interp, objv[objc-1], 0); } /* @@ -2665,8 +2612,7 @@ ForeachLoopStep( } TclNRAddCallback(interp, ForeachLoopStep, statePtr, NULL, NULL, NULL); - return TclNREvalObjEx(interp, statePtr->bodyPtr, 0, - ((Interp *) interp)->cmdFramePtr, statePtr->bodyIdx); + return TclNREvalObjEx(interp, statePtr->bodyPtr, 0); } /* diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 59e0991..a726932 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -117,12 +117,6 @@ static int InfoCompleteCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int InfoDefaultCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -/* TIP #348 - New 'info' subcommand 'errorstack' */ -static int InfoErrorStackCmd(ClientData dummy, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -/* TIP #280 - New 'info' subcommand 'frame' */ -static int InfoFrameCmd(ClientData dummy, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); static int InfoFunctionsCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int InfoHostnameCmd(ClientData dummy, Tcl_Interp *interp, @@ -165,9 +159,7 @@ static const EnsembleImplMap defaultInfoMap[] = { {"complete", InfoCompleteCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"coroutine", TclInfoCoroutineCmd, TclCompileInfoCoroutineCmd, NULL, NULL, 0}, {"default", InfoDefaultCmd, TclCompileBasic3ArgCmd, NULL, NULL, 0}, - {"errorstack", InfoErrorStackCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"exists", TclInfoExistsCmd, TclCompileInfoExistsCmd, NULL, NULL, 0}, - {"frame", InfoFrameCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"functions", InfoFunctionsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"globals", TclInfoGlobalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"hostname", InfoHostnameCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, @@ -251,7 +243,6 @@ IfConditionCallback( Tcl_Interp *interp, int result) { - Interp *iPtr = (Interp *) interp; int objc = PTR2INT(data[0]); Tcl_Obj *const *objv = data[1]; int i = PTR2INT(data[2]); @@ -298,8 +289,7 @@ IfConditionCallback( * TIP #280. Make invoking context available to branch. */ - return TclNREvalObjEx(interp, objv[thenScriptIndex], 0, - iPtr->cmdFramePtr, thenScriptIndex); + return TclNREvalObjEx(interp, objv[thenScriptIndex], 0); } return TCL_OK; } @@ -355,10 +345,9 @@ IfConditionCallback( * TIP #280. Make invoking context available to branch/else. */ - return TclNREvalObjEx(interp, objv[thenScriptIndex], 0, - iPtr->cmdFramePtr, thenScriptIndex); + return TclNREvalObjEx(interp, objv[thenScriptIndex], 0); } - return TclNREvalObjEx(interp, objv[i], 0, iPtr->cmdFramePtr, i); + return TclNREvalObjEx(interp, objv[i], 0); missingScript: Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -986,55 +975,6 @@ InfoDefaultCmd( /* *---------------------------------------------------------------------- * - * InfoErrorStackCmd -- - * - * Called to implement the "info errorstack" command that returns information - * about the last error's call stack. Handles the following syntax: - * - * info errorstack ?interp? - * - * Results: - * Returns TCL_OK if successful and TCL_ERROR if there is an error. - * - * Side effects: - * Returns a result in the interpreter's result object. If there is an - * error, the result is an error message. - * - *---------------------------------------------------------------------- - */ - -static int -InfoErrorStackCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tcl_Interp *target; - Interp *iPtr; - - if ((objc != 1) && (objc != 2)) { - Tcl_WrongNumArgs(interp, 1, objv, "?interp?"); - return TCL_ERROR; - } - - target = interp; - if (objc == 2) { - target = Tcl_GetSlave(interp, Tcl_GetString(objv[1])); - if (target == NULL) { - return TCL_ERROR; - } - } - - iPtr = (Interp *) target; - Tcl_SetObjResult(interp, iPtr->errorStack); - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * * TclInfoExistsCmd -- * * Called to implement the "info exists" command that determines whether @@ -1078,347 +1018,6 @@ TclInfoExistsCmd( /* *---------------------------------------------------------------------- * - * InfoFrameCmd -- - * TIP #280 - * - * Called to implement the "info frame" command that returns the location - * of either the currently executing command, or its caller. Handles the - * following syntax: - * - * info frame ?number? - * - * Results: - * Returns TCL_OK if successful and TCL_ERROR if there is an error. - * - * Side effects: - * Returns a result in the interpreter's result object. If there is an - * error, the result is an error message. - * - *---------------------------------------------------------------------- - */ - -static int -InfoFrameCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Interp *iPtr = (Interp *) interp; - int level, code = TCL_OK; - CmdFrame *framePtr, **cmdFramePtrPtr = &iPtr->cmdFramePtr; - CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; - int topLevel = 0; - - if (objc > 2) { - Tcl_WrongNumArgs(interp, 1, objv, "?number?"); - return TCL_ERROR; - } - - while (corPtr) { - while (*cmdFramePtrPtr) { - topLevel++; - cmdFramePtrPtr = &((*cmdFramePtrPtr)->nextPtr); - } - if (corPtr->caller.cmdFramePtr) { - *cmdFramePtrPtr = corPtr->caller.cmdFramePtr; - } - corPtr = corPtr->callerEEPtr->corPtr; - } - topLevel += (*cmdFramePtrPtr)->level; - - if (topLevel != iPtr->cmdFramePtr->level) { - framePtr = iPtr->cmdFramePtr; - while (framePtr) { - framePtr->level = topLevel--; - framePtr = framePtr->nextPtr; - } - if (topLevel) { - Tcl_Panic("Broken frame level calculation"); - } - topLevel = iPtr->cmdFramePtr->level; - } - - if (objc == 1) { - /* - * Just "info frame". - */ - - Tcl_SetObjResult(interp, Tcl_NewIntObj(topLevel)); - goto done; - } - - /* - * We've got "info frame level" and must parse the level first. - */ - - if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) { - code = TCL_ERROR; - goto done; - } - - if ((level > topLevel) || (level <= - topLevel)) { - levelError: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad level \"%s\"", TclGetString(objv[1]))); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_FRAME", - TclGetString(objv[1]), NULL); - code = TCL_ERROR; - goto done; - } - - /* - * Let us convert to relative so that we know how many levels to go back - */ - - if (level > 0) { - level -= topLevel; - } - - framePtr = iPtr->cmdFramePtr; - while (++level <= 0) { - framePtr = framePtr->nextPtr; - if (!framePtr) { - goto levelError; - } - } - - Tcl_SetObjResult(interp, TclInfoFrame(interp, framePtr)); - - done: - cmdFramePtrPtr = &iPtr->cmdFramePtr; - corPtr = iPtr->execEnvPtr->corPtr; - while (corPtr) { - CmdFrame *endPtr = corPtr->caller.cmdFramePtr; - - if (endPtr) { - if (*cmdFramePtrPtr == endPtr) { - *cmdFramePtrPtr = NULL; - } else { - CmdFrame *runPtr = *cmdFramePtrPtr; - - while (runPtr->nextPtr != endPtr) { - runPtr->level -= endPtr->level; - runPtr = runPtr->nextPtr; - } - runPtr->level = 1; - runPtr->nextPtr = NULL; - } - cmdFramePtrPtr = &corPtr->caller.cmdFramePtr; - } - corPtr = corPtr->callerEEPtr->corPtr; - } - return code; -} - -/* - *---------------------------------------------------------------------- - * - * TclInfoFrame -- - * - * Core of InfoFrameCmd, returns TIP280 dict for a given frame. - * - * Results: - * Returns TIP280 dict. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj * -TclInfoFrame( - Tcl_Interp *interp, /* Current interpreter. */ - CmdFrame *framePtr) /* Frame to get info for. */ -{ - Interp *iPtr = (Interp *) interp; - Tcl_Obj *tmpObj; - Tcl_Obj *lv[20]; /* Keep uptodate when more keys are added to - * the dict. */ - int lc = 0; - /* - * This array is indexed by the TCL_LOCATION_... values, except - * for _LAST. - */ - static const char *const typeString[TCL_LOCATION_LAST] = { - "eval", "eval", "eval", "precompiled", "source", "proc" - }; - Proc *procPtr = framePtr->framePtr ? framePtr->framePtr->procPtr : NULL; - int needsFree = -1; - - /* - * Pull the information and construct the dictionary to return, as list. - * Regarding use of the CmdFrame fields see tclInt.h, and its definition. - */ - -#define ADD_PAIR(name, value) \ - TclNewLiteralStringObj(tmpObj, name); \ - lv[lc++] = tmpObj; \ - lv[lc++] = (value) - - switch (framePtr->type) { - case TCL_LOCATION_EVAL: - /* - * Evaluation, dynamic script. Type, line, cmd, the latter through - * str. - */ - - ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1)); - if (framePtr->line) { - ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0])); - } else { - ADD_PAIR("line", Tcl_NewIntObj(1)); - } - ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL)); - break; - - case TCL_LOCATION_PREBC: - /* - * Precompiled. Result contains the type as signal, nothing else. - */ - - ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1)); - break; - - case TCL_LOCATION_BC: { - /* - * Execution of bytecode. Talk to the BC engine to fill out the frame. - */ - - CmdFrame *fPtr = TclStackAlloc(interp, sizeof(CmdFrame)); - - *fPtr = *framePtr; - - /* - * Note: - * Type BC => f.data.eval.path is not used. - * f.data.tebc.codePtr is used instead. - */ - - TclGetSrcInfoForPc(fPtr); - - /* - * Now filled: cmd.str.(cmd,len), line - * Possibly modified: type, path! - */ - - ADD_PAIR("type", Tcl_NewStringObj(typeString[fPtr->type], -1)); - if (fPtr->line) { - ADD_PAIR("line", Tcl_NewIntObj(fPtr->line[0])); - } - - if (fPtr->type == TCL_LOCATION_SOURCE) { - ADD_PAIR("file", fPtr->data.eval.path); - - /* - * Death of reference by TclGetSrcInfoForPc. - */ - - Tcl_DecrRefCount(fPtr->data.eval.path); - } - - ADD_PAIR("cmd", TclGetSourceFromFrame(fPtr, 0, NULL)); - if (fPtr->cmdObj && framePtr->cmdObj == NULL) { - needsFree = lc - 1; - } - TclStackFree(interp, fPtr); - break; - } - - case TCL_LOCATION_SOURCE: - /* - * Evaluation of a script file. - */ - - ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1)); - ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0])); - ADD_PAIR("file", framePtr->data.eval.path); - - /* - * Refcount framePtr->data.eval.path goes up when lv is converted into - * the result list object. - */ - - ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL)); - break; - - case TCL_LOCATION_PROC: - Tcl_Panic("TCL_LOCATION_PROC found in standard frame"); - break; - } - - /* - * 'proc'. Common to all frame types. Conditional on having an associated - * Procedure CallFrame. - */ - - if (procPtr != NULL) { - Tcl_HashEntry *namePtr = procPtr->cmdPtr->hPtr; - - if (namePtr) { - Tcl_Obj *procNameObj; - - /* - * This is a regular command. - */ - - TclNewObj(procNameObj); - Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr, - procNameObj); - ADD_PAIR("proc", procNameObj); - } else if (procPtr->cmdPtr->clientData) { - ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData; - int i; - - /* - * This is a non-standard command. Luckily, it's told us how to - * render extra information about its frame. - */ - - for (i=0 ; i<efiPtr->length ; i++) { - lv[lc++] = Tcl_NewStringObj(efiPtr->fields[i].name, -1); - if (efiPtr->fields[i].proc) { - lv[lc++] = - efiPtr->fields[i].proc(efiPtr->fields[i].clientData); - } else { - lv[lc++] = efiPtr->fields[i].clientData; - } - } - } - } - - /* - * 'level'. Common to all frame types. Conditional on having an associated - * _visible_ CallFrame. - */ - - if ((framePtr->framePtr != NULL) && (iPtr->varFramePtr != NULL)) { - CallFrame *current = framePtr->framePtr; - CallFrame *top = iPtr->varFramePtr; - CallFrame *idx; - - for (idx=top ; idx!=NULL ; idx=idx->callerVarPtr) { - if (idx == current) { - int c = framePtr->framePtr->level; - int t = iPtr->varFramePtr->level; - - ADD_PAIR("level", Tcl_NewIntObj(t - c)); - break; - } - } - } - - tmpObj = Tcl_NewListObj(lc, lv); - if (needsFree >= 0) { - Tcl_DecrRefCount(lv[needsFree]); - } - return tmpObj; -} - -/* - *---------------------------------------------------------------------- - * * InfoFunctionsCmd -- * * Called to implement the "info functions" command that returns the list diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 13f9e7d..4655891 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -3539,12 +3539,6 @@ TclNRSwitchObjCmd( Tcl_Obj *stringObj, *indexVarObj, *matchVarObj; Tcl_Obj *const *savedObjv = objv; Tcl_RegExp regExpr = NULL; - Interp *iPtr = (Interp *) interp; - int pc = 0; - int bidx = 0; /* Index of body argument. */ - Tcl_Obj *blist = NULL; /* List obj which is the body */ - CmdFrame *ctxPtr; /* Copy of the topmost cmdframe, to allow us - * to mess with the line information */ /* * If you add options that make -e and -g not unique prefixes of -exact or @@ -3668,22 +3662,16 @@ TclNRSwitchObjCmd( stringObj = objv[i]; objc -= i + 1; objv += i + 1; - bidx = i + 1; /* First after the match string. */ /* * If all of the pattern/command pairs are lumped into a single argument, * split them out again. - * - * TIP #280: Determine the lines the words in the list start at, based on - * the same data for the list word itself. The cmdFramePtr line - * information is manipulated directly. */ splitObjs = 0; if (objc == 1) { Tcl_Obj **listv; - blist = objv[0]; if (TclListObjGetElements(interp, objv[0], &objc, &listv) != TCL_OK){ return TCL_ERROR; } @@ -3911,58 +3899,6 @@ TclNRSwitchObjCmd( */ matchFound: - ctxPtr = TclStackAlloc(interp, sizeof(CmdFrame)); - *ctxPtr = *iPtr->cmdFramePtr; - - if (splitObjs) { - /* - * We have to perform the GetSrc and other type dependent handling of - * the frame here because we are munging with the line numbers, - * something the other commands like if, etc. are not doing. Them are - * fine with simply passing the CmdFrame through and having the - * special handling done in 'info frame', or the bc compiler - */ - - if (ctxPtr->type == TCL_LOCATION_BC) { - /* - * Type BC => ctxPtr->data.eval.path is not used. - * ctxPtr->data.tebc.codePtr is used instead. - */ - - TclGetSrcInfoForPc(ctxPtr); - pc = 1; - - /* - * The line information in the cmdFrame is now a copy we do not - * own. - */ - } - - if (ctxPtr->type == TCL_LOCATION_SOURCE && ctxPtr->line[bidx] >= 0) { - int bline = ctxPtr->line[bidx]; - - ctxPtr->line = ckalloc(objc * sizeof(int)); - ctxPtr->nline = objc; - TclListLines(blist, bline, objc, ctxPtr->line, objv); - } else { - /* - * This is either a dynamic code word, when all elements are - * relative to themselves, or something else less expected and - * where we have no information. The result is the same in both - * cases; tell the code to come that it doesn't know where it is, - * which triggers reversion to the old behavior. - */ - - int k; - - ctxPtr->line = ckalloc(objc * sizeof(int)); - ctxPtr->nline = objc; - for (k=0; k < objc; k++) { - ctxPtr->line[k] = -1; - } - } - } - for (j = i + 1; ; j += 2) { if (j >= objc) { /* @@ -3977,13 +3913,9 @@ TclNRSwitchObjCmd( } } - /* - * TIP #280: Make invoking context available to switch branch. - */ - - Tcl_NRAddCallback(interp, SwitchPostProc, INT2PTR(splitObjs), ctxPtr, - INT2PTR(pc), (ClientData) pattern); - return TclNREvalObjEx(interp, objv[j], 0, ctxPtr, splitObjs ? j : bidx+j); + Tcl_NRAddCallback(interp, SwitchPostProc, (ClientData) pattern, + NULL, NULL, NULL); + return TclNREvalObjEx(interp, objv[j], 0); } static int @@ -3994,28 +3926,10 @@ SwitchPostProc( { /* Unpack the preserved data */ - int splitObjs = PTR2INT(data[0]); - CmdFrame *ctxPtr = data[1]; - int pc = PTR2INT(data[2]); - const char *pattern = data[3]; + const char *pattern = data[0]; int patternLength = strlen(pattern); /* - * Clean up TIP 280 context information - */ - - if (splitObjs) { - ckfree(ctxPtr->line); - if (pc && (ctxPtr->type == TCL_LOCATION_SOURCE)) { - /* - * Death of SrcInfo reference. - */ - - Tcl_DecrRefCount(ctxPtr->data.eval.path); - } - } - - /* * Generate an error message if necessary. */ @@ -4028,7 +3942,6 @@ SwitchPostProc( (overflow ? limit : patternLength), pattern, (overflow ? "..." : ""), Tcl_GetErrorLine(interp))); } - TclStackFree(interp, ctxPtr); return result; } @@ -4357,8 +4270,7 @@ TclNRTryObjCmd( Tcl_NRAddCallback(interp, TryPostBody, handlersObj, finallyObj, (ClientData)objv, INT2PTR(objc)); - return TclNREvalObjEx(interp, bodyObj, 0, - ((Interp *) interp)->cmdFramePtr, 1); + return TclNREvalObjEx(interp, bodyObj, 0); } /* @@ -4573,8 +4485,7 @@ TryPostBody( Tcl_NRAddCallback(interp, TryPostHandler, objv, options, info[0], INT2PTR((finallyObj == NULL) ? 0 : objc - 1)); Tcl_DecrRefCount(handlersObj); - return TclNREvalObjEx(interp, handlerBodyObj, 0, - ((Interp *) interp)->cmdFramePtr, 4*i + 5); + return TclNREvalObjEx(interp, handlerBodyObj, 0); handlerFailed: resultObj = Tcl_GetObjResult(interp); @@ -4600,8 +4511,7 @@ TryPostBody( if (finallyObj != NULL) { Tcl_NRAddCallback(interp, TryPostFinal, resultObj, options, cmdObj, NULL); - return TclNREvalObjEx(interp, finallyObj, 0, - ((Interp *) interp)->cmdFramePtr, objc - 1); + return TclNREvalObjEx(interp, finallyObj, 0); } /* @@ -4680,14 +4590,11 @@ TryPostHandler( */ if (finallyObj != NULL) { - Interp *iPtr = (Interp *) interp; - Tcl_NRAddCallback(interp, TryPostFinal, resultObj, options, cmdObj, NULL); /* The 'finally' script is always the last argument word. */ - return TclNREvalObjEx(interp, finallyObj, 0, iPtr->cmdFramePtr, - finally); + return TclNREvalObjEx(interp, finallyObj, 0); } /* @@ -4797,8 +4704,6 @@ TclNRWhileObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - ForIterData *iterPtr; - if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "test command"); return TCL_ERROR; @@ -4807,16 +4712,8 @@ TclNRWhileObjCmd( /* * We reuse [for]'s callback, passing a NULL for the 'next' script. */ - - TclSmallAllocEx(interp, sizeof(ForIterData), iterPtr); - iterPtr->cond = objv[1]; - iterPtr->body = objv[2]; - iterPtr->next = NULL; - iterPtr->msg = "\n (\"while\" body line %d)"; - iterPtr->word = 2; - - TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL, - NULL, NULL); + TclNRAddCallback(interp, TclNRForIterCallback, /*cond*/ objv[1], + /*body*/ objv[2], /*next*/ NULL, NULL); return TCL_OK; } @@ -4848,27 +4745,12 @@ TclListLines( * derived continuation data */ { const char *listStr = Tcl_GetString(listObj); - const char *listHead = listStr; int i, length = strlen(listStr); const char *element = NULL, *next = NULL; - ContLineLoc *clLocPtr = TclContinuationsGet(listObj); - int *clNext = (clLocPtr ? &clLocPtr->loc[0] : NULL); for (i = 0; i < n; i++) { TclFindElement(NULL, listStr, length, &element, &next, NULL, NULL); - TclAdvanceLines(&line, listStr, element); - /* Leading whitespace */ - TclAdvanceContinuations(&line, &clNext, element - listHead); - if (elems && clNext) { - TclContinuationsEnterDerived(elems[i], element-listHead, clNext); - } - lines[i] = line; - length -= (next - listStr); - TclAdvanceLines(&line, element, next); - /* Element */ - listStr = next; - if (*element == 0) { /* ASSERT i == n */ break; diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index d3be2b0..e4dba8e 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -124,7 +124,6 @@ TclCompileAppendCmd( { Tcl_Token *varTokenPtr, *valueTokenPtr; int isScalar, localIndex, numWords, i; - DefineLineInformation; /* TIP #280 */ /* TODO: Consider support for compiling expanded args. */ numWords = parsePtr->numWords; @@ -155,8 +154,7 @@ TclCompileAppendCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, 0, - &localIndex, &isScalar, 1); + TclPushVarName(interp, varTokenPtr, envPtr, 0, &localIndex, &isScalar); /* * We are doing an assignment, otherwise TclCompileSetCmd was called, so @@ -165,7 +163,7 @@ TclCompileAppendCmd( */ valueTokenPtr = TokenAfter(varTokenPtr); - CompileWord(envPtr, valueTokenPtr, interp, 2); + CompileWord(envPtr, valueTokenPtr, interp); /* * Emit instructions to set/get the variable. @@ -207,7 +205,7 @@ TclCompileAppendCmd( valueTokenPtr = TokenAfter(varTokenPtr); for (i = 2 ; i < numWords ; i++) { - CompileWord(envPtr, valueTokenPtr, interp, i); + CompileWord(envPtr, valueTokenPtr, interp); valueTokenPtr = TokenAfter(valueTokenPtr); } TclEmitInstInt4( INST_REVERSE, numWords-2, envPtr); @@ -248,7 +246,6 @@ TclCompileArrayExistsCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; int isScalar, localIndex; @@ -257,8 +254,7 @@ TclCompileArrayExistsCmd( } tokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, tokenPtr, envPtr, TCL_NO_ELEMENT, - &localIndex, &isScalar, 1); + TclPushVarName(interp, tokenPtr, envPtr, TCL_NO_ELEMENT, &localIndex, &isScalar); if (!isScalar) { return TCL_ERROR; } @@ -280,7 +276,6 @@ TclCompileArraySetCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *varTokenPtr, *dataTokenPtr; int isScalar, localIndex, code = TCL_OK; int isDataLiteral, isDataValid, isDataEven, len; @@ -324,8 +319,7 @@ TclCompileArraySetCmd( goto done; } - PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT, - &localIndex, &isScalar, 1); + TclPushVarName(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT, &localIndex, &isScalar); if (!isScalar) { code = TCL_ERROR; goto done; @@ -391,7 +385,7 @@ TclCompileArraySetCmd( * Start issuing instructions to write to the array. */ - CompileWord(envPtr, dataTokenPtr, interp, 2); + CompileWord(envPtr, dataTokenPtr, interp); if (!isDataLiteral || !isDataValid) { /* * Only need this safety check if we're handling a non-literal or list @@ -442,7 +436,6 @@ TclCompileArrayUnsetCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); int isScalar, localIndex; int jumpEnd, jumpPop; @@ -451,8 +444,7 @@ TclCompileArrayUnsetCmd( return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } - PushVarNameWord(interp, tokenPtr, envPtr, TCL_NO_ELEMENT, - &localIndex, &isScalar, 1); + TclPushVarName(interp, tokenPtr, envPtr, TCL_NO_ELEMENT, &localIndex, &isScalar); if (!isScalar) { return TCL_ERROR; } @@ -571,7 +563,6 @@ TclCompileCatchCmd( int jumpFixup; Tcl_Token *cmdTokenPtr, *resultNameTokenPtr, *optsNameTokenPtr; int resultIndex, optsIndex, range, rangeFlags; - DefineLineInformation; /* TIP #280 */ int depth = TclGetStackDepth(envPtr); /* @@ -639,7 +630,6 @@ TclCompileCatchCmd( ExceptionRangeStarts(envPtr, range); BODY(cmdTokenPtr, 1); } else { - SetLineInformation(1); CompileTokens(envPtr, cmdTokenPtr, interp); ExceptionRangeStarts(envPtr, range); envPtr->exceptArrayPtr[range].stackDepth--; @@ -720,7 +710,6 @@ TclCompileConcatCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Obj *objPtr, *listObj; Tcl_Token *tokenPtr; int i; @@ -772,7 +761,7 @@ TclCompileConcatCmd( for (i = 1, tokenPtr = parsePtr->tokenPtr; i < parsePtr->numWords; i++) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); } TclEmitInstInt4( INST_CONCAT_STK, i-1, envPtr); @@ -876,7 +865,6 @@ TclCompileDictSetCmd( { Tcl_Token *tokenPtr; int i, dictVarIndex; - DefineLineInformation; /* TIP #280 */ Tcl_Token *varTokenPtr; /* @@ -905,7 +893,7 @@ TclCompileDictSetCmd( tokenPtr = TokenAfter(varTokenPtr); for (i=2 ; i< parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } @@ -928,7 +916,6 @@ TclCompileDictIncrCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *varTokenPtr, *keyTokenPtr; int dictVarIndex, incrAmount; @@ -985,7 +972,7 @@ TclCompileDictIncrCmd( * Emit the key and the code to actually do the increment. */ - CompileWord(envPtr, keyTokenPtr, interp, 2); + CompileWord(envPtr, keyTokenPtr, interp); TclEmitInstInt4( INST_DICT_INCR_IMM, incrAmount, envPtr); TclEmitInt4( dictVarIndex, envPtr); return TCL_OK; @@ -1002,7 +989,6 @@ TclCompileDictGetCmd( { Tcl_Token *tokenPtr; int i; - DefineLineInformation; /* TIP #280 */ /* * There must be at least two arguments after the command (the single-arg @@ -1020,7 +1006,7 @@ TclCompileDictGetCmd( */ for (i=1 ; i<parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } TclEmitInstInt4(INST_DICT_GET, parsePtr->numWords-2, envPtr); @@ -1039,7 +1025,6 @@ TclCompileDictExistsCmd( { Tcl_Token *tokenPtr; int i; - DefineLineInformation; /* TIP #280 */ /* * There must be at least two arguments after the command (the single-arg @@ -1057,7 +1042,7 @@ TclCompileDictExistsCmd( */ for (i=1 ; i<parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } TclEmitInstInt4(INST_DICT_EXISTS, parsePtr->numWords-2, envPtr); @@ -1075,7 +1060,6 @@ TclCompileDictUnsetCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr; - DefineLineInformation; /* TIP #280 */ int i, dictVarIndex; /* @@ -1106,7 +1090,7 @@ TclCompileDictUnsetCmd( for (i=2 ; i<parsePtr->numWords ; i++) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); } /* @@ -1127,7 +1111,6 @@ TclCompileDictCreateCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ int worker; /* Temp var for building the value in. */ Tcl_Token *tokenPtr; Tcl_Obj *keyObj, *valueObj, *dictObj; @@ -1196,9 +1179,9 @@ TclCompileDictCreateCmd( TclEmitOpcode( INST_POP, envPtr); tokenPtr = TokenAfter(parsePtr->tokenPtr); for (i=1 ; i<parsePtr->numWords ; i+=2) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, i+1); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); TclEmitInstInt4( INST_DICT_SET, 1, envPtr); TclEmitInt4( worker, envPtr); @@ -1220,7 +1203,6 @@ TclCompileDictMergeCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; int i, workerIndex, infoIndex, outLoop, jumpTarget; @@ -1235,7 +1217,7 @@ TclCompileDictMergeCmd( return TCL_OK; } else if (parsePtr->numWords == 2) { tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_DICT_VERIFY, envPtr); return TCL_OK; @@ -1259,7 +1241,7 @@ TclCompileDictMergeCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_DICT_VERIFY, envPtr); Emit14Inst( INST_STORE_SCALAR, workerIndex, envPtr); @@ -1279,7 +1261,7 @@ TclCompileDictMergeCmd( */ tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); TclEmitInstInt4( INST_DICT_FIRST, infoIndex, envPtr); TclEmitForwardJump(envPtr, JUMP_TRUE, &jumpPop); jumpTarget = CurrentOffset(envPtr); @@ -1363,7 +1345,6 @@ CompileDictEachCmd( * construct a new dictionary with the loop * body result. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr; int keyVarIndex, valueVarIndex, nameChars, loopRange, catchRange; int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset; @@ -1459,7 +1440,7 @@ CompileDictEachCmd( * this point. */ - CompileWord(envPtr, dictTokenPtr, interp, 2); + CompileWord(envPtr, dictTokenPtr, interp); /* * Now we catch errors from here on so that we can finalize the search @@ -1579,7 +1560,6 @@ TclCompileDictUpdateCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ int i, dictIndex, numVars, range, infoIndex; Tcl_Token **keyTokenPtrs, *dictVarTokenPtr, *bodyTokenPtr, *tokenPtr; DictUpdateInfo *duiPtr; @@ -1658,7 +1638,7 @@ TclCompileDictUpdateCmd( infoIndex = TclCreateAuxData(duiPtr, &dictUpdateInfoType, envPtr); for (i=0 ; i<numVars ; i++) { - CompileWord(envPtr, keyTokenPtrs[i], interp, 2*i+2); + CompileWord(envPtr, keyTokenPtrs[i], interp); } TclEmitInstInt4( INST_LIST, numVars, envPtr); TclEmitInstInt4( INST_DICT_UPDATE_START, dictIndex, envPtr); @@ -1727,7 +1707,6 @@ TclCompileDictAppendCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; int i, dictVarIndex; @@ -1758,7 +1737,7 @@ TclCompileDictAppendCmd( tokenPtr = TokenAfter(tokenPtr); for (i=2 ; i<parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } if (parsePtr->numWords > 4) { @@ -1782,7 +1761,6 @@ TclCompileDictLappendCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *varTokenPtr, *keyTokenPtr, *valueTokenPtr; int dictVarIndex; @@ -1812,8 +1790,8 @@ TclCompileDictLappendCmd( * Issue the implementation. */ - CompileWord(envPtr, keyTokenPtr, interp, 2); - CompileWord(envPtr, valueTokenPtr, interp, 3); + CompileWord(envPtr, keyTokenPtr, interp); + CompileWord(envPtr, valueTokenPtr, interp); TclEmitInstInt4( INST_DICT_LAPPEND, dictVarIndex, envPtr); return TCL_OK; } @@ -1827,7 +1805,6 @@ TclCompileDictWithCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ int i, range, varNameTmp = -1, pathTmp = -1, keysTmp, gotPath; int dictVar, bodyIsEmpty = 1; Tcl_Token *varTokenPtr, *tokenPtr; @@ -1898,7 +1875,7 @@ TclCompileDictWithCmd( tokenPtr = TokenAfter(varTokenPtr); for (i=2 ; i<parsePtr->numWords-1 ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } TclEmitInstInt4(INST_LIST, parsePtr->numWords-3,envPtr); @@ -1925,7 +1902,7 @@ TclCompileDictWithCmd( tokenPtr = varTokenPtr; for (i=1 ; i<parsePtr->numWords-1 ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } TclEmitInstInt4(INST_LIST, parsePtr->numWords-3,envPtr); @@ -1939,7 +1916,7 @@ TclCompileDictWithCmd( * Case: Direct dict in non-simple var with empty body. */ - CompileWord(envPtr, varTokenPtr, interp, 1); + CompileWord(envPtr, varTokenPtr, interp); TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_LOAD_STK, envPtr); PushStringLiteral(envPtr, ""); @@ -1974,13 +1951,13 @@ TclCompileDictWithCmd( */ if (dictVar == -1) { - CompileWord(envPtr, varTokenPtr, interp, 1); + CompileWord(envPtr, varTokenPtr, interp); Emit14Inst( INST_STORE_SCALAR, varNameTmp, envPtr); } tokenPtr = TokenAfter(varTokenPtr); if (gotPath) { for (i=2 ; i<parsePtr->numWords-1 ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } TclEmitInstInt4( INST_LIST, parsePtr->numWords-3,envPtr); @@ -2174,7 +2151,6 @@ TclCompileErrorCmd( */ Tcl_Token *tokenPtr; - DefineLineInformation; /* TIP #280 */ if (parsePtr->numWords < 2 || parsePtr->numWords > 4) { return TCL_ERROR; @@ -2185,7 +2161,7 @@ TclCompileErrorCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); /* * Construct the options. Note that -code and -level are not here. @@ -2196,13 +2172,13 @@ TclCompileErrorCmd( } else { PushStringLiteral(envPtr, "-errorinfo"); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); if (parsePtr->numWords == 3) { TclEmitInstInt4( INST_LIST, 2, envPtr); } else { PushStringLiteral(envPtr, "-errorcode"); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 3); + CompileWord(envPtr, tokenPtr, interp); TclEmitInstInt4( INST_LIST, 4, envPtr); } } @@ -2249,13 +2225,6 @@ TclCompileExprCmd( return TCL_ERROR; } - /* - * TIP #280: Use the per-word line information of the current command. - */ - - envPtr->line = envPtr->extCmdMapPtr->loc[ - envPtr->extCmdMapPtr->nuloc-1].line[1]; - firstWordPtr = TokenAfter(parsePtr->tokenPtr); TclCompileExprWords(interp, firstWordPtr, parsePtr->numWords-1, envPtr); return TCL_OK; @@ -2292,7 +2261,6 @@ TclCompileForCmd( int jumpEvalCondFixup; int bodyCodeOffset, jumpDist; int bodyRange, nextRange; - DefineLineInformation; /* TIP #280 */ if (parsePtr->numWords != 5) { return TCL_ERROR; @@ -2374,7 +2342,6 @@ TclCompileForCmd( TclFixupForwardJumpToHere(envPtr, jumpEvalCondFixup); - SetLineInformation(2); TclCompileExprWords(interp, testTokenPtr, 1, envPtr); jumpDist = CurrentOffset(envPtr) - bodyCodeOffset; @@ -2492,7 +2459,6 @@ CompileEachloopCmd( int infoIndex, range; int numWords, numLists, i, j, code = TCL_OK; Tcl_Obj *varListObj = NULL; - DefineLineInformation; /* TIP #280 */ /* * If the foreach command isn't in a procedure, don't compile it inline: @@ -2607,7 +2573,7 @@ CompileEachloopCmd( i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { if ((i%2 == 0) && (i > 0)) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); } } @@ -2862,7 +2828,6 @@ TclCompileFormatCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = parsePtr->tokenPtr; Tcl_Obj **objv, *formatObj, *tmpObj; char *bytes, *start; @@ -3012,7 +2977,7 @@ TclCompileFormatCmd( * directly. */ - CompileWord(envPtr, tokenPtr, interp, j); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); j++; i++; diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 7965ef1..273e3f1 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -110,7 +110,6 @@ TclCompileGlobalCmd( { Tcl_Token *varTokenPtr; int localIndex, numWords, i; - DefineLineInformation; /* TIP #280 */ /* TODO: Consider support for compiling expanded args. */ numWords = parsePtr->numWords; @@ -147,7 +146,7 @@ TclCompileGlobalCmd( /* TODO: Consider what value can pass throug the * IndexTailVarIfKnown() screen. Full CompileWord() * likely does not apply here. Push known value instead. */ - CompileWord(envPtr, varTokenPtr, interp, i); + CompileWord(envPtr, varTokenPtr, interp); TclEmitInstInt4( INST_NSUPVAR, localIndex, envPtr); } @@ -202,7 +201,6 @@ TclCompileIfCmd( * "if 0 {..}" */ int boolVal; /* Value of static condition. */ int compileScripts = 1; - DefineLineInformation; /* TIP #280 */ /* * Only compile the "if" command if all arguments are simple words, in @@ -278,7 +276,6 @@ TclCompileIfCmd( compileScripts = 0; } } else { - SetLineInformation(wordIdx); Tcl_ResetResult(interp); TclCompileExprWords(interp, testTokenPtr, 1, envPtr); if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) { @@ -337,11 +334,7 @@ TclCompileIfCmd( jumpEndFixupArray.fixup+jumpIndex); /* - * Fix the target of the jumpFalse after the test. Generate a 4 - * byte jump if the distance is > 120 bytes. This is conservative, - * and ensures that we won't have to replace this jump if we later - * also need to replace the proceeding jump to the end of the "if" - * with a 4 byte jump. + * Fix the target of the jumpFalse after the test. */ TclAdjustStackDepth(-1, envPtr); @@ -462,7 +455,6 @@ TclCompileIncrCmd( { Tcl_Token *varTokenPtr, *incrTokenPtr; int isScalar, localIndex, haveImmValue, immValue; - DefineLineInformation; /* TIP #280 */ if ((parsePtr->numWords != 2) && (parsePtr->numWords != 3)) { return TCL_ERROR; @@ -470,8 +462,8 @@ TclCompileIncrCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX, - &localIndex, &isScalar, 1); + TclPushVarName(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX, + &localIndex, &isScalar); /* * If an increment is given, push it, but see first if it's a small @@ -498,7 +490,6 @@ TclCompileIncrCmd( PushLiteral(envPtr, word, numBytes); } } else { - SetLineInformation(2); CompileTokens(envPtr, incrTokenPtr, interp); } } else { /* No incr amount given so use 1. */ @@ -571,7 +562,6 @@ TclCompileInfoCommandsCmd( * compiled. */ CompileEnv *envPtr) { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; Tcl_Obj *objPtr; char *bytes; @@ -610,7 +600,7 @@ TclCompileInfoCommandsCmd( */ /* TODO: Just push the known value */ - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode( INST_RESOLVE_COMMAND, envPtr); TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_STR_LEN, envPtr); @@ -659,7 +649,6 @@ TclCompileInfoExistsCmd( { Tcl_Token *tokenPtr; int isScalar, localIndex; - DefineLineInformation; /* TIP #280 */ if (parsePtr->numWords != 2) { return TCL_ERROR; @@ -674,7 +663,7 @@ TclCompileInfoExistsCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, tokenPtr, envPtr, 0, &localIndex, &isScalar, 1); + TclPushVarName(interp, tokenPtr, envPtr, 0, &localIndex, &isScalar); /* * Emit instruction to check the variable for existence. @@ -719,14 +708,12 @@ TclCompileInfoLevelCmd( } else if (parsePtr->numWords != 2) { return TCL_ERROR; } else { - DefineLineInformation; /* TIP #280 */ - /* * Compile the argument, then add the instruction to convert it into a * list of arguments. */ - CompileWord(envPtr, TokenAfter(parsePtr->tokenPtr), interp, 1); + CompileWord(envPtr, TokenAfter(parsePtr->tokenPtr), interp); TclEmitOpcode( INST_INFO_LEVEL_ARGS, envPtr); } return TCL_OK; @@ -741,13 +728,12 @@ TclCompileInfoObjectClassCmd( * compiled. */ CompileEnv *envPtr) { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); if (parsePtr->numWords != 2) { return TCL_ERROR; } - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode( INST_TCLOO_CLASS, envPtr); return TCL_OK; } @@ -761,7 +747,6 @@ TclCompileInfoObjectIsACmd( * compiled. */ CompileEnv *envPtr) { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); /* @@ -783,7 +768,7 @@ TclCompileInfoObjectIsACmd( * Issue the code. */ - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode( INST_TCLOO_IS_OBJECT, envPtr); return TCL_OK; } @@ -797,13 +782,12 @@ TclCompileInfoObjectNamespaceCmd( * compiled. */ CompileEnv *envPtr) { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); if (parsePtr->numWords != 2) { return TCL_ERROR; } - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode( INST_TCLOO_NS, envPtr); return TCL_OK; } @@ -837,7 +821,6 @@ TclCompileLappendCmd( { Tcl_Token *varTokenPtr, *valueTokenPtr; int isScalar, localIndex, numWords, i; - DefineLineInformation; /* TIP #280 */ /* TODO: Consider support for compiling expanded args. */ numWords = parsePtr->numWords; @@ -859,8 +842,8 @@ TclCompileLappendCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, 0, - &localIndex, &isScalar, 1); + TclPushVarName(interp, varTokenPtr, envPtr, 0, + &localIndex, &isScalar); /* * If we are doing an assignment, push the new value. In the no values @@ -870,7 +853,7 @@ TclCompileLappendCmd( if (numWords > 2) { Tcl_Token *valueTokenPtr = TokenAfter(varTokenPtr); - CompileWord(envPtr, valueTokenPtr, interp, 2); + CompileWord(envPtr, valueTokenPtr, interp); } /* @@ -900,11 +883,11 @@ TclCompileLappendCmd( lappendMultiple: varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, 0, - &localIndex, &isScalar, 1); + TclPushVarName(interp, varTokenPtr, envPtr, 0, + &localIndex, &isScalar); valueTokenPtr = TokenAfter(varTokenPtr); for (i = 2 ; i < numWords ; i++) { - CompileWord(envPtr, valueTokenPtr, interp, i); + CompileWord(envPtr, valueTokenPtr, interp); valueTokenPtr = TokenAfter(valueTokenPtr); } TclEmitInstInt4( INST_LIST, numWords-2, envPtr); @@ -953,7 +936,6 @@ TclCompileLassignCmd( { Tcl_Token *tokenPtr; int isScalar, localIndex, numWords, idx; - DefineLineInformation; /* TIP #280 */ numWords = parsePtr->numWords; @@ -970,7 +952,7 @@ TclCompileLassignCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); /* * Generate code to assign values from the list to variables. @@ -983,8 +965,8 @@ TclCompileLassignCmd( * Generate the next variable name. */ - PushVarNameWord(interp, tokenPtr, envPtr, 0, &localIndex, - &isScalar, idx+2); + TclPushVarName(interp, tokenPtr, envPtr, 0, &localIndex, + &isScalar); /* * Emit instructions to get the idx'th item out of the list value on @@ -1057,7 +1039,6 @@ TclCompileLindexCmd( { Tcl_Token *idxTokenPtr, *valTokenPtr; int i, idx, numWords = parsePtr->numWords; - DefineLineInformation; /* TIP #280 */ /* * Quit if too few args. @@ -1084,7 +1065,7 @@ TclCompileLindexCmd( * an "immediate lindex" which is the most efficient variety. */ - CompileWord(envPtr, valTokenPtr, interp, 1); + CompileWord(envPtr, valTokenPtr, interp); TclEmitInstInt4( INST_LIST_INDEX_IMM, idx, envPtr); return TCL_OK; } @@ -1101,7 +1082,7 @@ TclCompileLindexCmd( emitComplexLindex: for (i=1 ; i<numWords ; i++) { - CompileWord(envPtr, valTokenPtr, interp, i); + CompileWord(envPtr, valTokenPtr, interp); valTokenPtr = TokenAfter(valTokenPtr); } @@ -1146,7 +1127,6 @@ TclCompileListCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *valueTokenPtr; int i, numWords, concat, build; Tcl_Obj *listObj, *objPtr; @@ -1200,7 +1180,7 @@ TclCompileListCmd( build = 0; concat = 1; } - CompileWord(envPtr, valueTokenPtr, interp, i); + CompileWord(envPtr, valueTokenPtr, interp); if (valueTokenPtr->type == TCL_TOKEN_EXPAND_WORD) { if (concat) { TclEmitOpcode( INST_LIST_CONCAT, envPtr); @@ -1261,14 +1241,13 @@ TclCompileLlengthCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *varTokenPtr; - DefineLineInformation; /* TIP #280 */ if (parsePtr->numWords != 2) { return TCL_ERROR; } varTokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, varTokenPtr, interp, 1); + CompileWord(envPtr, varTokenPtr, interp); TclEmitOpcode( INST_LIST_LENGTH, envPtr); return TCL_OK; } @@ -1294,7 +1273,6 @@ TclCompileLrangeCmd( CompileEnv *envPtr) /* Holds the resulting instructions. */ { Tcl_Token *tokenPtr, *listTokenPtr; - DefineLineInformation; /* TIP #280 */ int idx1, idx2; if (parsePtr->numWords != 4) { @@ -1324,7 +1302,7 @@ TclCompileLrangeCmd( * is worth trying to do that given current knowledge. */ - CompileWord(envPtr, listTokenPtr, interp, 1); + CompileWord(envPtr, listTokenPtr, interp); TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr); TclEmitInt4( idx2, envPtr); return TCL_OK; @@ -1351,7 +1329,6 @@ TclCompileLinsertCmd( CompileEnv *envPtr) /* Holds the resulting instructions. */ { Tcl_Token *tokenPtr, *listTokenPtr; - DefineLineInformation; /* TIP #280 */ int idx, i; if (parsePtr->numWords < 3) { @@ -1377,7 +1354,7 @@ TclCompileLinsertCmd( * this is a splice (== split, insert values as list, concat-3). */ - CompileWord(envPtr, listTokenPtr, interp, 1); + CompileWord(envPtr, listTokenPtr, interp); if (parsePtr->numWords == 3) { TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); TclEmitInt4( INDEX_END, envPtr); @@ -1386,7 +1363,7 @@ TclCompileLinsertCmd( for (i=3 ; i<parsePtr->numWords ; i++) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); } TclEmitInstInt4( INST_LIST, i-3, envPtr); @@ -1433,7 +1410,6 @@ TclCompileLreplaceCmd( CompileEnv *envPtr) /* Holds the resulting instructions. */ { Tcl_Token *tokenPtr, *listTokenPtr; - DefineLineInformation; /* TIP #280 */ Tcl_Obj *tmpObj; int idx1, idx2, i, offset, offset2; @@ -1467,7 +1443,7 @@ TclCompileLreplaceCmd( */ tmpObj = NULL; - CompileWord(envPtr, listTokenPtr, interp, 1); + CompileWord(envPtr, listTokenPtr, interp); if (parsePtr->numWords == 4) { if (idx1 == 0) { if (idx2 == INDEX_END) { @@ -1491,7 +1467,7 @@ TclCompileLreplaceCmd( tokenPtr = TokenAfter(tokenPtr); for (i=4 ; i<parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } TclEmitInstInt4( INST_LIST, i - 4, envPtr); @@ -1694,7 +1670,6 @@ TclCompileLsetCmd( int localIndex; /* Index of var in local var table. */ int isScalar; /* Flag == 1 if scalar, 0 if array. */ int i; - DefineLineInformation; /* TIP #280 */ /* * Check argument count. @@ -1718,8 +1693,8 @@ TclCompileLsetCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, 0, - &localIndex, &isScalar, 1); + TclPushVarName(interp, varTokenPtr, envPtr, 0, + &localIndex, &isScalar); /* * Push the "index" args and the new element value. @@ -1727,7 +1702,7 @@ TclCompileLsetCmd( for (i=2 ; i<parsePtr->numWords ; ++i) { varTokenPtr = TokenAfter(varTokenPtr); - CompileWord(envPtr, varTokenPtr, interp, i); + CompileWord(envPtr, varTokenPtr, interp); } /* @@ -1860,7 +1835,6 @@ TclCompileNamespaceCodeCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr; - DefineLineInformation; /* TIP #280 */ if (parsePtr->numWords != 2) { return TCL_ERROR; @@ -1895,7 +1869,7 @@ TclCompileNamespaceCodeCmd( PushStringLiteral(envPtr, "::namespace"); PushStringLiteral(envPtr, "inscope"); TclEmitOpcode( INST_NS_CURRENT, envPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); TclEmitInstInt4( INST_LIST, 4, envPtr); return TCL_OK; } @@ -1910,14 +1884,13 @@ TclCompileNamespaceOriginCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr; - DefineLineInformation; /* TIP #280 */ if (parsePtr->numWords != 2) { return TCL_ERROR; } tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode( INST_ORIGIN_COMMAND, envPtr); return TCL_OK; } @@ -1932,14 +1905,13 @@ TclCompileNamespaceQualifiersCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); - DefineLineInformation; /* TIP #280 */ int off; if (parsePtr->numWords != 2) { return TCL_ERROR; } - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); PushStringLiteral(envPtr, "0"); PushStringLiteral(envPtr, "::"); TclEmitInstInt4( INST_OVER, 2, envPtr); @@ -1968,7 +1940,6 @@ TclCompileNamespaceTailCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); - DefineLineInformation; /* TIP #280 */ int jumpFixup; if (parsePtr->numWords != 2) { @@ -1979,7 +1950,7 @@ TclCompileNamespaceTailCmd( * Take care; only add 2 to found index if the string was actually found. */ - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); PushStringLiteral(envPtr, "::"); TclEmitInstInt4( INST_OVER, 1, envPtr); TclEmitOpcode( INST_STR_FIND_LAST, envPtr); @@ -2006,7 +1977,6 @@ TclCompileNamespaceUpvarCmd( { Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr; int localIndex, numWords, i; - DefineLineInformation; /* TIP #280 */ if (envPtr->procPtr == NULL) { return TCL_ERROR; @@ -2026,7 +1996,7 @@ TclCompileNamespaceUpvarCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); /* * Loop over the (otherVar, thisVar) pairs. If any of the thisVar is not a @@ -2039,7 +2009,7 @@ TclCompileNamespaceUpvarCmd( otherTokenPtr = TokenAfter(localTokenPtr); localTokenPtr = TokenAfter(otherTokenPtr); - CompileWord(envPtr, otherTokenPtr, interp, i); + CompileWord(envPtr, otherTokenPtr, interp); localIndex = LocalScalarFromToken(localTokenPtr, envPtr); if (localIndex < 0) { return TCL_ERROR; @@ -2065,7 +2035,6 @@ TclCompileNamespaceWhichCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr, *opt; int idx; @@ -2097,7 +2066,7 @@ TclCompileNamespaceWhichCmd( * Issue the bytecode. */ - CompileWord(envPtr, tokenPtr, interp, idx); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode( INST_RESOLVE_COMMAND, envPtr); return TCL_OK; } @@ -2133,7 +2102,6 @@ TclCompileRegexpCmd( * parse of the RE or string. */ int i, len, nocase, exact, sawLast, simple; const char *str; - DefineLineInformation; /* TIP #280 */ /* * We are only interested in compiling simple regexp cases. Currently @@ -2236,7 +2204,7 @@ TclCompileRegexpCmd( } if (!simple) { - CompileWord(envPtr, varTokenPtr, interp, parsePtr->numWords-2); + CompileWord(envPtr, varTokenPtr, interp); } /* @@ -2244,7 +2212,7 @@ TclCompileRegexpCmd( */ varTokenPtr = TokenAfter(varTokenPtr); - CompileWord(envPtr, varTokenPtr, interp, parsePtr->numWords-1); + CompileWord(envPtr, varTokenPtr, interp); if (simple) { if (exact && !nocase) { @@ -2314,7 +2282,6 @@ TclCompileRegsubCmd( * The only optional part is the "--", and no other options are handled. */ - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr, *stringTokenPtr; Tcl_Obj *patternObj = NULL, *replacementObj = NULL; Tcl_DString pattern; @@ -2428,7 +2395,7 @@ TclCompileRegsubCmd( PushLiteral(envPtr, bytes, len); bytes = Tcl_GetStringFromObj(replacementObj, &len); PushLiteral(envPtr, bytes, len); - CompileWord(envPtr, stringTokenPtr, interp, parsePtr->numWords-2); + CompileWord(envPtr, stringTokenPtr, interp); TclEmitOpcode( INST_STR_MAP, envPtr); done: @@ -2479,7 +2446,6 @@ TclCompileReturnCmd( int numOptionWords = numWords - 1 - explicitResult; Tcl_Obj *returnOpts, **objv; Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr); - DefineLineInformation; /* TIP #280 */ /* * Check for special case which can always be compiled: @@ -2496,8 +2462,8 @@ TclCompileReturnCmd( Tcl_Token *optsTokenPtr = TokenAfter(wordTokenPtr); Tcl_Token *msgTokenPtr = TokenAfter(optsTokenPtr); - CompileWord(envPtr, optsTokenPtr, interp, 2); - CompileWord(envPtr, msgTokenPtr, interp, 3); + CompileWord(envPtr, optsTokenPtr, interp); + CompileWord(envPtr, msgTokenPtr, interp); TclEmitInstInt4(INST_REVERSE, 2, envPtr); TclEmitInvoke(envPtr, INST_RETURN_STK); return TCL_OK; @@ -2558,7 +2524,7 @@ TclCompileReturnCmd( */ if (explicitResult) { - CompileWord(envPtr, wordTokenPtr, interp, numWords-1); + CompileWord(envPtr, wordTokenPtr, interp); } else { /* * No explict result argument, so default result is empty string. @@ -2619,7 +2585,7 @@ TclCompileReturnCmd( wordTokenPtr = TokenAfter(parsePtr->tokenPtr); for (objc=1 ; objc<=numOptionWords ; objc++) { - CompileWord(envPtr, wordTokenPtr, interp, objc); + CompileWord(envPtr, wordTokenPtr, interp); wordTokenPtr = TokenAfter(wordTokenPtr); } TclEmitInstInt4(INST_LIST, numOptionWords, envPtr); @@ -2629,7 +2595,7 @@ TclCompileReturnCmd( */ if (explicitResult) { - CompileWord(envPtr, wordTokenPtr, interp, numWords-1); + CompileWord(envPtr, wordTokenPtr, interp); } else { PushStringLiteral(envPtr, ""); } @@ -2665,10 +2631,9 @@ TclCompileSyntaxError( int numBytes; const char *bytes = TclGetStringFromObj(msg, &numBytes); - TclErrorStackResetIf(interp, bytes, numBytes); TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, numBytes), envPtr); CompileReturnInternal(envPtr, INST_SYNTAX, TCL_ERROR, 0, - TclNoErrorStack(interp, Tcl_GetReturnOptions(interp, TCL_ERROR))); + Tcl_GetReturnOptions(interp, TCL_ERROR)); Tcl_ResetResult(interp); } @@ -2701,7 +2666,6 @@ TclCompileUpvarCmd( { Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr; int localIndex, numWords, i; - DefineLineInformation; /* TIP #280 */ Tcl_Obj *objPtr; if (envPtr->procPtr == NULL) { @@ -2737,7 +2701,7 @@ TclCompileUpvarCmd( return TCL_ERROR; } /* TODO: Push the known value instead? */ - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); otherTokenPtr = TokenAfter(tokenPtr); i = 2; } else { @@ -2762,7 +2726,7 @@ TclCompileUpvarCmd( for (; i<numWords; i+=2, otherTokenPtr = TokenAfter(localTokenPtr)) { localTokenPtr = TokenAfter(otherTokenPtr); - CompileWord(envPtr, otherTokenPtr, interp, i); + CompileWord(envPtr, otherTokenPtr, interp); localIndex = LocalScalarFromToken(localTokenPtr, envPtr); if (localIndex < 0) { return TCL_ERROR; @@ -2808,7 +2772,6 @@ TclCompileVariableCmd( { Tcl_Token *varTokenPtr, *valueTokenPtr; int localIndex, numWords, i; - DefineLineInformation; /* TIP #280 */ numWords = parsePtr->numWords; if (numWords < 2) { @@ -2841,7 +2804,7 @@ TclCompileVariableCmd( /* TODO: Consider what value can pass throug the * IndexTailVarIfKnown() screen. Full CompileWord() * likely does not apply here. Push known value instead. */ - CompileWord(envPtr, varTokenPtr, interp, i); + CompileWord(envPtr, varTokenPtr, interp); TclEmitInstInt4( INST_VARIABLE, localIndex, envPtr); if (i+1 < numWords) { @@ -2849,7 +2812,7 @@ TclCompileVariableCmd( * A value has been given: set the variable, pop the value */ - CompileWord(envPtr, valueTokenPtr, interp, i+1); + CompileWord(envPtr, valueTokenPtr, interp); Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr); TclEmitOpcode( INST_POP, envPtr); } @@ -2978,7 +2941,6 @@ TclCompileObjectNextCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = parsePtr->tokenPtr; int i; @@ -2987,7 +2949,7 @@ TclCompileObjectNextCmd( } for (i=0 ; i<parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } TclEmitInstInt1( INST_TCLOO_NEXT, i, envPtr); @@ -3003,7 +2965,6 @@ TclCompileObjectNextToCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = parsePtr->tokenPtr; int i; @@ -3012,7 +2973,7 @@ TclCompileObjectNextToCmd( } for (i=0 ; i<parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } TclEmitInstInt1( INST_TCLOO_NEXT_CLASS, i, envPtr); diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 06f17ab..93568df 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -46,12 +46,10 @@ static int CompileUnaryOpCmd(Tcl_Interp *interp, static void IssueSwitchChainedTests(Tcl_Interp *interp, CompileEnv *envPtr, int mode, int noCase, int valueIndex, int numWords, - Tcl_Token **bodyToken, int *bodyLines, - int **bodyNext); + Tcl_Token **bodyToken); static void IssueSwitchJumpTable(Tcl_Interp *interp, CompileEnv *envPtr, int valueIndex, - int numWords, Tcl_Token **bodyToken, - int *bodyLines, int **bodyContLines); + int numWords, Tcl_Token **bodyToken); static int IssueTryClausesInstructions(Tcl_Interp *interp, CompileEnv *envPtr, Tcl_Token *bodyToken, int numHandlers, int *matchCodes, @@ -189,7 +187,6 @@ TclCompileSetCmd( { Tcl_Token *varTokenPtr, *valueTokenPtr; int isAssignment, isScalar, localIndex, numWords; - DefineLineInformation; /* TIP #280 */ numWords = parsePtr->numWords; if ((numWords != 2) && (numWords != 3)) { @@ -206,8 +203,8 @@ TclCompileSetCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, 0, - &localIndex, &isScalar, 1); + TclPushVarName(interp, varTokenPtr, envPtr, 0, + &localIndex, &isScalar); /* * If we are doing an assignment, push the new value. @@ -215,7 +212,7 @@ TclCompileSetCmd( if (isAssignment) { valueTokenPtr = TokenAfter(varTokenPtr); - CompileWord(envPtr, valueTokenPtr, interp, 2); + CompileWord(envPtr, valueTokenPtr, interp); } /* @@ -276,7 +273,6 @@ TclCompileStringCatCmd( int i, numWords = parsePtr->numWords, numArgs; Tcl_Token *wordTokenPtr; Tcl_Obj *obj, *folded; - DefineLineInformation; /* TIP #280 */ /* Trivial case, no arg */ @@ -311,7 +307,7 @@ TclCompileStringCatCmd( folded = NULL; numArgs ++; } - CompileWord(envPtr, wordTokenPtr, interp, i); + CompileWord(envPtr, wordTokenPtr, interp); numArgs ++; if (numArgs >= 254) { /* 254 to take care of the possible +1 of "folded" above */ TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr); @@ -345,7 +341,6 @@ TclCompileStringCmpCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; /* @@ -361,9 +356,9 @@ TclCompileStringCmpCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode(INST_STR_CMP, envPtr); return TCL_OK; } @@ -377,7 +372,6 @@ TclCompileStringEqualCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; /* @@ -393,9 +387,9 @@ TclCompileStringEqualCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode(INST_STR_EQ, envPtr); return TCL_OK; } @@ -409,7 +403,6 @@ TclCompileStringFirstCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; /* @@ -425,9 +418,9 @@ TclCompileStringFirstCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); OP(STR_FIND); return TCL_OK; } @@ -441,7 +434,6 @@ TclCompileStringLastCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; /* @@ -457,9 +449,9 @@ TclCompileStringLastCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); OP(STR_FIND_LAST); return TCL_OK; } @@ -473,7 +465,6 @@ TclCompileStringIndexCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; if (parsePtr->numWords != 3) { @@ -485,9 +476,9 @@ TclCompileStringIndexCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode(INST_STR_INDEX, envPtr); return TCL_OK; } @@ -501,7 +492,6 @@ TclCompileStringIsCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); static const char *const isClasses[] = { "alnum", "alpha", "ascii", "control", @@ -573,7 +563,7 @@ TclCompileStringIsCmd( * 5. Lists */ - CompileWord(envPtr, tokenPtr, interp, parsePtr->numWords-1); + CompileWord(envPtr, tokenPtr, interp); switch ((enum isClasses) t) { case STR_IS_ALNUM: @@ -778,7 +768,6 @@ TclCompileStringMatchCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; int i, length, exactMatch = 0, nocase = 0; const char *str; @@ -832,7 +821,6 @@ TclCompileStringMatchCmd( } PushLiteral(envPtr, str, length); } else { - SetLineInformation(i+1+nocase); CompileTokens(envPtr, tokenPtr, interp); } tokenPtr = TokenAfter(tokenPtr); @@ -859,7 +847,6 @@ TclCompileStringLenCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; Tcl_Obj *objPtr; @@ -882,7 +869,6 @@ TclCompileStringLenCmd( len = sprintf(buf, "%d", len); PushLiteral(envPtr, buf, len); } else { - SetLineInformation(1); CompileTokens(envPtr, tokenPtr, interp); TclEmitOpcode(INST_STR_LEN, envPtr); } @@ -899,7 +885,6 @@ TclCompileStringMapCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *mapTokenPtr, *stringTokenPtr; Tcl_Obj *mapObj, **objv; char *bytes; @@ -941,12 +926,12 @@ TclCompileStringMapCmd( bytes = Tcl_GetStringFromObj(objv[0], &len); if (len == 0) { - CompileWord(envPtr, stringTokenPtr, interp, 2); + CompileWord(envPtr, stringTokenPtr, interp); } else { PushLiteral(envPtr, bytes, len); bytes = Tcl_GetStringFromObj(objv[1], &len); PushLiteral(envPtr, bytes, len); - CompileWord(envPtr, stringTokenPtr, interp, 2); + CompileWord(envPtr, stringTokenPtr, interp); OP(STR_MAP); } Tcl_DecrRefCount(mapObj); @@ -962,7 +947,6 @@ TclCompileStringRangeCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *stringTokenPtr, *fromTokenPtr, *toTokenPtr; int idx1, idx2; @@ -988,7 +972,7 @@ TclCompileStringRangeCmd( * Push the operand onto the stack and then the substring operation. */ - CompileWord(envPtr, stringTokenPtr, interp, 1); + CompileWord(envPtr, stringTokenPtr, interp); OP44( STR_RANGE_IMM, idx1, idx2); return TCL_OK; @@ -997,9 +981,9 @@ TclCompileStringRangeCmd( */ nonConstantIndices: - CompileWord(envPtr, stringTokenPtr, interp, 1); - CompileWord(envPtr, fromTokenPtr, interp, 2); - CompileWord(envPtr, toTokenPtr, interp, 3); + CompileWord(envPtr, stringTokenPtr, interp); + CompileWord(envPtr, fromTokenPtr, interp); + CompileWord(envPtr, toTokenPtr, interp); OP( STR_RANGE); return TCL_OK; } @@ -1014,7 +998,6 @@ TclCompileStringReplaceCmd( CompileEnv *envPtr) /* Holds the resulting instructions. */ { Tcl_Token *tokenPtr, *valueTokenPtr, *replacementTokenPtr = NULL; - DefineLineInformation; /* TIP #280 */ int idx1, idx2; if (parsePtr->numWords < 4 || parsePtr->numWords > 5) { @@ -1057,14 +1040,14 @@ TclCompileStringReplaceCmd( * Just working with the first character. */ - CompileWord(envPtr, valueTokenPtr, interp, 1); + CompileWord(envPtr, valueTokenPtr, interp); if (replacementTokenPtr == NULL) { /* Drop first */ OP44( STR_RANGE_IMM, 1, INDEX_END); return TCL_OK; } /* Replace first */ - CompileWord(envPtr, replacementTokenPtr, interp, 4); + CompileWord(envPtr, replacementTokenPtr, interp); OP4( OVER, 1); PUSH( ""); OP( STR_EQ); @@ -1086,14 +1069,14 @@ TclCompileStringReplaceCmd( * Just working with the last character. */ - CompileWord(envPtr, valueTokenPtr, interp, 1); + CompileWord(envPtr, valueTokenPtr, interp); if (replacementTokenPtr == NULL) { /* Drop last */ OP44( STR_RANGE_IMM, 0, INDEX_END-1); return TCL_OK; } /* Replace last */ - CompileWord(envPtr, replacementTokenPtr, interp, 4); + CompileWord(envPtr, replacementTokenPtr, interp); OP4( OVER, 1); PUSH( ""); OP( STR_EQ); @@ -1118,13 +1101,13 @@ TclCompileStringReplaceCmd( */ genericReplace: - CompileWord(envPtr, valueTokenPtr, interp, 1); + CompileWord(envPtr, valueTokenPtr, interp); tokenPtr = TokenAfter(valueTokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 3); + CompileWord(envPtr, tokenPtr, interp); if (replacementTokenPtr != NULL) { - CompileWord(envPtr, replacementTokenPtr, interp, 4); + CompileWord(envPtr, replacementTokenPtr, interp); } else { PUSH( ""); } @@ -1142,7 +1125,6 @@ TclCompileStringTrimLCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; if (parsePtr->numWords != 2 && parsePtr->numWords != 3) { @@ -1150,10 +1132,10 @@ TclCompileStringTrimLCmd( } tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); if (parsePtr->numWords == 3) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); } else { PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet)); } @@ -1170,7 +1152,6 @@ TclCompileStringTrimRCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; if (parsePtr->numWords != 2 && parsePtr->numWords != 3) { @@ -1178,10 +1159,10 @@ TclCompileStringTrimRCmd( } tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); if (parsePtr->numWords == 3) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); } else { PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet)); } @@ -1198,7 +1179,6 @@ TclCompileStringTrimCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; if (parsePtr->numWords != 2 && parsePtr->numWords != 3) { @@ -1206,10 +1186,10 @@ TclCompileStringTrimCmd( } tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); if (parsePtr->numWords == 3) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); } else { PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet)); } @@ -1226,7 +1206,6 @@ TclCompileStringToUpperCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; if (parsePtr->numWords != 2) { @@ -1234,7 +1213,7 @@ TclCompileStringToUpperCmd( } tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); OP( STR_UPPER); return TCL_OK; } @@ -1248,7 +1227,6 @@ TclCompileStringToLowerCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; if (parsePtr->numWords != 2) { @@ -1256,7 +1234,7 @@ TclCompileStringToLowerCmd( } tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); OP( STR_LOWER); return TCL_OK; } @@ -1270,7 +1248,6 @@ TclCompileStringToTitleCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; if (parsePtr->numWords != 2) { @@ -1278,7 +1255,7 @@ TclCompileStringToTitleCmd( } tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); OP( STR_TITLE); return TCL_OK; } @@ -1353,7 +1330,6 @@ TclCompileSubstCmd( Tcl_Obj **objv/*, *toSubst = NULL*/; Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr); int code = TCL_ERROR; - DefineLineInformation; /* TIP #280 */ if (numArgs == 0) { return TCL_ERROR; @@ -1397,9 +1373,8 @@ TclCompileSubstCmd( return TCL_ERROR; } - SetLineInformation(numArgs); TclSubstCompile(interp, wordTokenPtr[1].start, wordTokenPtr[1].size, - flags, mapPtr->loc[eclIndex].line[numArgs], envPtr); + flags, envPtr); /* TclDecrRefCount(toSubst);*/ return TCL_OK; @@ -1411,11 +1386,10 @@ TclSubstCompile( const char *bytes, int numBytes, int flags, - int line, CompileEnv *envPtr) { Tcl_Token *endTokenPtr, *tokenPtr; - int breakOffset = -1, count = 0, bline = line; + int breakOffset = -1, count = 0; Tcl_Parse parse; Tcl_InterpState state = NULL; @@ -1449,8 +1423,6 @@ TclSubstCompile( literal = TclRegisterNewLiteral(envPtr, tokenPtr->start, tokenPtr->size); TclEmitPush(literal, envPtr); - TclAdvanceLines(&bline, tokenPtr->start, - tokenPtr->start + tokenPtr->size); count++; continue; case TCL_TOKEN_BS: @@ -1483,9 +1455,7 @@ TclSubstCompile( } } - envPtr->line = bline; TclCompileVarSubst(interp, tokenPtr, envPtr); - bline = envPtr->line; count++; continue; } @@ -1510,8 +1480,6 @@ TclSubstCompile( FIXJUMP4(startFixup); } - envPtr->line = bline; - catchRange = TclCreateExceptRange(CATCH_EXCEPTION_FULL, envPtr); loopRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr); ExceptionRangeStarts(envPtr, catchRange); @@ -1571,7 +1539,6 @@ TclSubstCompile( /* CONTINUE jump to here */ ContinueTarget(envPtr, loopRange); - bline = envPtr->line; } while (count > 255) { @@ -1641,8 +1608,6 @@ TclCompileSwitchCmd( int foundMode = 0; /* Have we seen a mode flag yet? */ int i, valueIndex; int result = TCL_ERROR; - DefineLineInformation; /* TIP #280 */ - int *clNext = envPtr->clNext; /* * Only handle the following versions: @@ -1781,11 +1746,6 @@ TclCompileSwitchCmd( if (numWords == 1) { const char *bytes; int maxLen, numBytes; - int bline; /* TIP #280: line of the pattern/action list, - * and start of list for when tracking the - * location. This list comes immediately after - * the value we switch on. */ - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { return TCL_ERROR; } @@ -1802,9 +1762,8 @@ TclCompileSwitchCmd( bodyLines = ckalloc(sizeof(int) * maxLen); bodyContLines = ckalloc(sizeof(int*) * maxLen); - bline = mapPtr->loc[eclIndex].line[valueIndex+1]; numWords = 0; - + while (numBytes > 0) { const char *prevBytes = bytes; int literal; @@ -1819,19 +1778,6 @@ TclCompileSwitchCmd( bodyTokenArray[numWords].numComponents = 0; bodyToken[numWords] = bodyTokenArray + numWords; - /* - * TIP #280: Now determine the line the list element starts on - * (there is no need to do it earlier, due to the possibility of - * aborting, see above). - */ - - TclAdvanceLines(&bline, prevBytes, bodyTokenArray[numWords].start); - TclAdvanceContinuations(&bline, &clNext, - bodyTokenArray[numWords].start - envPtr->source); - bodyLines[numWords] = bline; - bodyContLines[numWords] = clNext; - TclAdvanceLines(&bline, bodyTokenArray[numWords].start, bytes); - TclAdvanceContinuations(&bline, &clNext, bytes - envPtr->source); numBytes -= (bytes - prevBytes); numWords++; @@ -1874,13 +1820,6 @@ TclCompileSwitchCmd( goto freeTemporaries; } bodyToken[i] = tokenPtr+1; - - /* - * TIP #280: Copy line information from regular cmd info. - */ - - bodyLines[i] = mapPtr->loc[eclIndex].line[valueIndex+1+i]; - bodyContLines[i] = mapPtr->loc[eclIndex].next[valueIndex+1+i]; tokenPtr = TokenAfter(tokenPtr); } } @@ -1904,14 +1843,13 @@ TclCompileSwitchCmd( */ /* Both methods push the value to match against onto the stack. */ - CompileWord(envPtr, valueTokenPtr, interp, valueIndex); + CompileWord(envPtr, valueTokenPtr, interp); if (mode == Switch_Exact) { - IssueSwitchJumpTable(interp, envPtr, valueIndex, numWords, bodyToken, - bodyLines, bodyContLines); + IssueSwitchJumpTable(interp, envPtr, valueIndex, numWords, bodyToken); } else { IssueSwitchChainedTests(interp, envPtr, mode, noCase, valueIndex, - numWords, bodyToken, bodyLines, bodyContLines); + numWords, bodyToken); } result = TCL_OK; @@ -1955,10 +1893,7 @@ IssueSwitchChainedTests( int numBodyTokens, /* Number of tokens describing things the * switch can match against and bodies to * execute when the match succeeds. */ - Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */ - int *bodyLines, /* Array of line numbers for body list - * items. */ - int **bodyContLines) /* Array of continuation line info. */ + Tcl_Token **bodyToken) /* Array of pointers to pattern list items. */ { enum {Switch_Exact, Switch_Glob, Switch_Regexp}; int foundDefault; /* Flag to indicate whether a "default" clause @@ -2124,8 +2059,6 @@ IssueSwitchChainedTests( */ OP( POP); - envPtr->line = bodyLines[i+1]; /* TIP #280 */ - envPtr->clNext = bodyContLines[i+1]; /* TIP #280 */ TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr); if (!foundDefault) { @@ -2187,10 +2120,7 @@ IssueSwitchJumpTable( int numBodyTokens, /* Number of tokens describing things the * switch can match against and bodies to * execute when the match succeeds. */ - Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */ - int *bodyLines, /* Array of line numbers for body list - * items. */ - int **bodyContLines) /* Array of continuation line info. */ + Tcl_Token **bodyToken) /* Array of continuation line info. */ { JumptableInfo *jtPtr; int infoIndex, isNew, *finalFixups, numRealBodies = 0, jumpLocation; @@ -2298,8 +2228,6 @@ IssueSwitchJumpTable( * Compile the body of the arm. */ - envPtr->line = bodyLines[i+1]; /* TIP #280 */ - envPtr->clNext = bodyContLines[i+1]; /* TIP #280 */ TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr); /* @@ -2485,7 +2413,6 @@ TclCompileTailcallCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = parsePtr->tokenPtr; int i; @@ -2496,10 +2423,10 @@ TclCompileTailcallCmd( /* make room for the nsObjPtr */ /* TODO: Doesn't this have to be a known value? */ - CompileWord(envPtr, tokenPtr, interp, 0); + CompileWord(envPtr, tokenPtr, interp); for (i=1 ; i<parsePtr->numWords ; i++) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); } TclEmitInstInt1( INST_TAILCALL, parsePtr->numWords, envPtr); return TCL_OK; @@ -2532,7 +2459,6 @@ TclCompileThrowCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ int numWords = parsePtr->numWords; Tcl_Token *codeToken, *msgToken; Tcl_Obj *objPtr; @@ -2554,10 +2480,10 @@ TclCompileThrowCmd( * must come first in case substitution raises errors. */ if (!codeKnown) { - CompileWord(envPtr, codeToken, interp, 1); + CompileWord(envPtr, codeToken, interp); PUSH( "-errorcode"); } - CompileWord(envPtr, msgToken, interp, 2); + CompileWord(envPtr, msgToken, interp); codeIsList = codeKnown && (TCL_OK == Tcl_ListObjLength(interp, objPtr, &len)); @@ -2654,7 +2580,6 @@ TclCompileTryCmd( * No handlers or finally; do nothing beyond evaluating the body. */ - DefineLineInformation; /* TIP #280 */ BODY(bodyToken, 1); return TCL_OK; } @@ -2871,7 +2796,6 @@ IssueTryClausesInstructions( int *optionVars, Tcl_Token **handlerTokens) { - DefineLineInformation; /* TIP #280 */ int range, resultVar, optionsVar; int i, j, len, forwardsNeedFixing = 0, trapZero = 0, afterBody = 0; int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource; @@ -3077,7 +3001,6 @@ IssueTryClausesFinallyInstructions( Tcl_Token **handlerTokens, Tcl_Token *finallyToken) /* Not NULL */ { - DefineLineInformation; /* TIP #280 */ int range, resultVar, optionsVar, i, j, len, forwardsNeedFixing = 0; int trapZero = 0, afterBody = 0, finalOK, finalError, noFinalError; int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource; @@ -3361,7 +3284,6 @@ IssueTryFinallyInstructions( Tcl_Token *bodyToken, Tcl_Token *finallyToken) { - DefineLineInformation; /* TIP #280 */ int range, jumpOK, jumpSplice, newTarget; /* @@ -3436,7 +3358,6 @@ TclCompileUnsetCmd( { Tcl_Token *varTokenPtr; int isScalar, localIndex, flags = 1, i, varCount = 0, haveFlags = 0; - DefineLineInformation; /* TIP #280 */ /* TODO: Consider support for compiling expanded args. */ @@ -3518,8 +3439,8 @@ TclCompileUnsetCmd( * namespace qualifiers. */ - PushVarNameWord(interp, varTokenPtr, envPtr, 0, - &localIndex, &isScalar, i); + TclPushVarName(interp, varTokenPtr, envPtr, 0, + &localIndex, &isScalar); /* * Emit instructions to unset the variable. @@ -3578,7 +3499,6 @@ TclCompileWhileCmd( int loopMayEnd = 1; /* This is set to 0 if it is recognized as an * infinite loop. */ Tcl_Obj *boolObj; - DefineLineInformation; /* TIP #280 */ if (parsePtr->numWords != 3) { return TCL_ERROR; @@ -3670,7 +3590,6 @@ TclCompileWhileCmd( testCodeOffset = CurrentOffset(envPtr); jumpDist = testCodeOffset - jumpEvalCondFixup; TclFixupForwardJump(envPtr, jumpEvalCondFixup, jumpDist); - SetLineInformation(1); TclCompileExprWords(interp, testTokenPtr, 1, envPtr); jumpDist = CurrentOffset(envPtr) - bodyCodeOffset; @@ -3732,10 +3651,9 @@ TclCompileYieldCmd( if (parsePtr->numWords == 1) { PUSH(""); } else { - DefineLineInformation; /* TIP #280 */ Tcl_Token *valueTokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, valueTokenPtr, interp, 1); + CompileWord(envPtr, valueTokenPtr, interp); } OP( YIELD); return TCL_OK; @@ -3768,7 +3686,6 @@ TclCompileYieldToCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); int i; @@ -3778,7 +3695,7 @@ TclCompileYieldToCmd( OP( NS_CURRENT); for (i = 1 ; i < parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); } OP4( LIST, i); @@ -3812,13 +3729,12 @@ CompileUnaryOpCmd( CompileEnv *envPtr) { Tcl_Token *tokenPtr; - DefineLineInformation; /* TIP #280 */ if (parsePtr->numWords != 2) { return TCL_ERROR; } tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode(instruction, envPtr); return TCL_OK; } @@ -3854,13 +3770,12 @@ CompileAssociativeBinaryOpCmd( CompileEnv *envPtr) { Tcl_Token *tokenPtr = parsePtr->tokenPtr; - DefineLineInformation; /* TIP #280 */ int words; /* TODO: Consider support for compiling expanded args. */ for (words=1 ; words<parsePtr->numWords ; words++) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, words); + CompileWord(envPtr, tokenPtr, interp); } if (parsePtr->numWords <= 2) { PushLiteral(envPtr, identity, -1); @@ -3939,16 +3854,15 @@ CompileComparisonOpCmd( CompileEnv *envPtr) { Tcl_Token *tokenPtr; - DefineLineInformation; /* TIP #280 */ /* TODO: Consider support for compiling expanded args. */ if (parsePtr->numWords < 3) { PUSH("1"); } else if (parsePtr->numWords == 3) { tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); TclEmitOpcode(instruction, envPtr); } else if (envPtr->procPtr == NULL) { /* @@ -3961,15 +3875,15 @@ CompileComparisonOpCmd( int words; tokenPtr = TokenAfter(parsePtr->tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, tokenPtr, interp); STORE(tmpIndex); TclEmitOpcode(instruction, envPtr); for (words=3 ; words<parsePtr->numWords ;) { LOAD(tmpIndex); tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, words); + CompileWord(envPtr, tokenPtr, interp); if (++words < parsePtr->numWords) { STORE(tmpIndex); } @@ -4106,12 +4020,11 @@ TclCompilePowOpCmd( */ Tcl_Token *tokenPtr = parsePtr->tokenPtr; - DefineLineInformation; /* TIP #280 */ int words; for (words=1 ; words<parsePtr->numWords ; words++) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, words); + CompileWord(envPtr, tokenPtr, interp); } if (parsePtr->numWords <= 2) { PUSH("1"); @@ -4276,7 +4189,6 @@ TclCompileMinusOpCmd( CompileEnv *envPtr) { Tcl_Token *tokenPtr = parsePtr->tokenPtr; - DefineLineInformation; /* TIP #280 */ int words; /* TODO: Consider support for compiling expanded args. */ @@ -4289,7 +4201,7 @@ TclCompileMinusOpCmd( } for (words=1 ; words<parsePtr->numWords ; words++) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, words); + CompileWord(envPtr, tokenPtr, interp); } if (words == 2) { TclEmitOpcode(INST_UMINUS, envPtr); @@ -4322,7 +4234,6 @@ TclCompileDivOpCmd( CompileEnv *envPtr) { Tcl_Token *tokenPtr = parsePtr->tokenPtr; - DefineLineInformation; /* TIP #280 */ int words; /* TODO: Consider support for compiling expanded args. */ @@ -4338,7 +4249,7 @@ TclCompileDivOpCmd( } for (words=1 ; words<parsePtr->numWords ; words++) { tokenPtr = TokenAfter(tokenPtr); - CompileWord(envPtr, tokenPtr, interp, words); + CompileWord(envPtr, tokenPtr, interp); } if (words <= 3) { TclEmitOpcode(INST_DIV, envPtr); diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 55623d6..280d563 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -2143,10 +2143,6 @@ TclCompileExpr( Tcl_Obj *const *litObjv; Tcl_Obj **funcObjv; - /* TIP #280 : Track Lines within the expression */ - TclAdvanceLines(&envPtr->line, script, - script + TclParseAllWhiteSpace(script, numBytes)); - TclListObjGetElements(NULL, litList, &objc, (Tcl_Obj ***)&litObjv); TclListObjGetElements(NULL, funcList, &objc, &funcObjv); CompileExprTree(interp, opTree, 0, &litObjv, funcObjv, @@ -2200,7 +2196,7 @@ ExecConstantExprTree( TclNRSetRoot(interp); envPtr = TclStackAlloc(interp, sizeof(CompileEnv)); - TclInitCompileEnv(interp, envPtr, NULL, 0, NULL, 0); + TclInitCompileEnv(interp, envPtr, NULL, 0); CompileExprTree(interp, nodes, index, litObjvPtr, NULL, NULL, envPtr, 0 /* optimize */); TclEmitOpcode(INST_DONE, envPtr); diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 946c977..e418f68 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -650,16 +650,6 @@ static int SetByteCodeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); /* - * TIP #280: Helper for building the per-word line information of all compiled - * commands. - */ -static void EnterCmdWordData(ExtCmdLoc *eclPtr, int srcOffset, - Tcl_Token *tokenPtr, const char *cmd, int len, - int numWords, int line, int *clNext, int **lines, - CompileEnv *envPtr); -static void ReleaseCmdWordData(ExtCmdLoc *eclPtr); - -/* * The structure below defines the bytecode Tcl object type by means of * procedures that can be invoked by generic object code. */ @@ -731,7 +721,6 @@ TclSetByteCodeFromAny( * in frame. */ int length, result = TCL_OK; const char *stringPtr; - ContLineLoc *clLocPtr; #ifdef TCL_COMPILE_DEBUG if (!traceInitialized) { @@ -751,25 +740,7 @@ TclSetByteCodeFromAny( * stored by TclCompEvalObj and ProcCompileProc. */ - TclInitCompileEnv(interp, &compEnv, stringPtr, length, - iPtr->invokeCmdFramePtr, iPtr->invokeWord); - - /* - * Now we check if we have data about invisible continuation lines for the - * script, and make it available to the compile environment, if so. - * - * It is not clear if the script Tcl_Obj* can be free'd while the compiler - * 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 in the function TclFreeCompileEnv(), - * found in this file. The "lineCLPtr" hashtable is managed in the file - * "tclObj.c". - */ - - clLocPtr = TclContinuationsGet(objPtr); - if (clLocPtr) { - compEnv.clNext = &clLocPtr->loc[0]; - } + TclInitCompileEnv(interp, &compEnv, stringPtr, length); TclCompileScript(interp, stringPtr, length, &compEnv); @@ -1034,24 +1005,6 @@ TclCleanupByteCode( auxDataPtr++; } - /* - * TIP #280. Release the location data associated with this byte code - * structure, if any. NOTE: The interp we belong to may be gone already, - * and the data with it. - * - * See also tclBasic.c, DeleteInterpProc - */ - - if (iPtr) { - Tcl_HashEntry *hePtr = Tcl_FindHashEntry(iPtr->lineBCPtr, - (char *) codePtr); - - if (hePtr) { - ReleaseCmdWordData(Tcl_GetHashValue(hePtr)); - Tcl_DeleteHashEntry(hePtr); - } - } - if (codePtr->localCachePtr && (--codePtr->localCachePtr->refCount == 0)) { TclFreeLocalCache(interp, codePtr->localCachePtr); } @@ -1174,9 +1127,9 @@ CompileSubstObj( const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes); /* TODO: Check for more TIP 280 */ - TclInitCompileEnv(interp, &compEnv, bytes, numBytes, NULL, 0); + TclInitCompileEnv(interp, &compEnv, bytes, numBytes); - TclSubstCompile(interp, bytes, numBytes, flags, 1, &compEnv); + TclSubstCompile(interp, bytes, numBytes, flags, &compEnv); TclEmitOpcode(INST_DONE, &compEnv); TclInitByteCodeObj(objPtr, &compEnv); @@ -1231,26 +1184,6 @@ FreeSubstCodeInternalRep( TclCleanupByteCode(codePtr); } } - -static void -ReleaseCmdWordData( - ExtCmdLoc *eclPtr) -{ - int i; - - if (eclPtr->type == TCL_LOCATION_SOURCE) { - Tcl_DecrRefCount(eclPtr->path); - } - for (i=0 ; i<eclPtr->nuloc ; i++) { - ckfree((char *) eclPtr->loc[i].line); - } - - if (eclPtr->loc != NULL) { - ckfree((char *) eclPtr->loc); - } - - ckfree((char *) eclPtr); -} /* *---------------------------------------------------------------------- @@ -1276,10 +1209,7 @@ TclInitCompileEnv( register CompileEnv *envPtr,/* Points to the CompileEnv structure to * initialize. */ const char *stringPtr, /* The source string to be compiled. */ - int numBytes, /* Number of bytes in source string. */ - const CmdFrame *invoker, /* Location context invoking the bcc */ - int word) /* Index of the word in that context getting - * compiled */ + int numBytes) /* Number of bytes in source string. */ { Interp *iPtr = (Interp *) interp; @@ -1315,137 +1245,6 @@ TclInitCompileEnv( envPtr->cmdMapEnd = COMPILEENV_INIT_CMD_MAP_SIZE; envPtr->mallocedCmdMap = 0; - /* - * TIP #280: Set up the extended command location information, based on - * the context invoking the byte code compiler. This structure is used to - * keep the per-word line information for all compiled commands. - * - * See also tclBasic.c, TclEvalObjEx, for the equivalent code in the - * non-compiling evaluator - */ - - envPtr->extCmdMapPtr = ckalloc(sizeof(ExtCmdLoc)); - envPtr->extCmdMapPtr->loc = NULL; - envPtr->extCmdMapPtr->nloc = 0; - envPtr->extCmdMapPtr->nuloc = 0; - envPtr->extCmdMapPtr->path = NULL; - - if (invoker == NULL) { - /* - * Initialize the compiler for relative counting in case of a - * dynamic context. - */ - - envPtr->line = 1; - if (iPtr->evalFlags & TCL_EVAL_FILE) { - iPtr->evalFlags &= ~TCL_EVAL_FILE; - envPtr->extCmdMapPtr->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. No place to put it. - * And no place to serve the error itself to either. Fake - * a path, empty string. - */ - - TclNewLiteralStringObj(envPtr->extCmdMapPtr->path, ""); - } else { - envPtr->extCmdMapPtr->path = norm; - } - } else { - TclNewLiteralStringObj(envPtr->extCmdMapPtr->path, ""); - } - - Tcl_IncrRefCount(envPtr->extCmdMapPtr->path); - } else { - envPtr->extCmdMapPtr->type = - (envPtr->procPtr ? TCL_LOCATION_PROC : TCL_LOCATION_BC); - } - } else { - /* - * Initialize the compiler using the context, making counting absolute - * to that context. Note that the context can be byte code execution. - * In that case we have to fill out the missing pieces (line, path, - * ...) which may make change the type as well. - */ - - CmdFrame *ctxPtr = TclStackAlloc(interp, sizeof(CmdFrame)); - int pc = 0; - - *ctxPtr = *invoker; - if (invoker->type == TCL_LOCATION_BC) { - /* - * Note: Type BC => ctx.data.eval.path is not used. - * ctx.data.tebc.codePtr is used instead. - */ - - TclGetSrcInfoForPc(ctxPtr); - pc = 1; - } - - if ((ctxPtr->nline <= word) || (ctxPtr->line[word] < 0)) { - /* - * Word is not a literal, relative counting. - */ - - envPtr->line = 1; - envPtr->extCmdMapPtr->type = - (envPtr->procPtr ? TCL_LOCATION_PROC : TCL_LOCATION_BC); - - if (pc && (ctxPtr->type == TCL_LOCATION_SOURCE)) { - /* - * The reference made by 'TclGetSrcInfoForPc' is dead. - */ - - Tcl_DecrRefCount(ctxPtr->data.eval.path); - } - } else { - envPtr->line = ctxPtr->line[word]; - envPtr->extCmdMapPtr->type = ctxPtr->type; - - if (ctxPtr->type == TCL_LOCATION_SOURCE) { - envPtr->extCmdMapPtr->path = ctxPtr->data.eval.path; - - if (pc) { - /* - * The reference 'TclGetSrcInfoForPc' made is transfered. - */ - - ctxPtr->data.eval.path = NULL; - } else { - /* - * We have a new reference here. - */ - - Tcl_IncrRefCount(envPtr->extCmdMapPtr->path); - } - } - } - - TclStackFree(interp, ctxPtr); - } - - envPtr->extCmdMapPtr->start = envPtr->line; - - /* - * Initialize the data about invisible continuation lines as empty, i.e. - * not used. The caller (TclSetByteCodeFromAny) will set this up, if such - * data is available. - */ - - envPtr->clNext = NULL; - envPtr->auxDataArrayPtr = envPtr->staticAuxDataArraySpace; envPtr->auxDataArrayNext = 0; envPtr->auxDataArrayEnd = COMPILEENV_INIT_AUX_DATA_SIZE; @@ -1523,10 +1322,6 @@ TclFreeCompileEnv( if (envPtr->mallocedAuxDataArray) { ckfree(envPtr->auxDataArrayPtr); } - if (envPtr->extCmdMapPtr) { - ReleaseCmdWordData(envPtr->extCmdMapPtr); - envPtr->extCmdMapPtr = NULL; - } } /* @@ -1668,7 +1463,6 @@ TclCompileInvocation( CompileEnv *envPtr) { int wordIdx = 0, depth = TclGetStackDepth(envPtr); - DefineLineInformation; if (cmdObj) { CompileCmdLiteral(interp, cmdObj, envPtr); @@ -1679,8 +1473,6 @@ TclCompileInvocation( for (; wordIdx < numWords; wordIdx++, tokenPtr = TokenAfter(tokenPtr)) { int objIdx; - SetLineInformation(wordIdx); - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { CompileTokens(envPtr, tokenPtr, interp); continue; @@ -1688,10 +1480,6 @@ TclCompileInvocation( objIdx = TclRegisterNewLiteral(envPtr, tokenPtr[1].start, tokenPtr[1].size); - if (envPtr->clNext) { - TclContinuationsEnterDerived(TclFetchLiteral(envPtr, objIdx), - tokenPtr[1].start - envPtr->source, envPtr->clNext); - } TclEmitPush(objIdx, envPtr); } @@ -1712,7 +1500,6 @@ CompileExpanded( CompileEnv *envPtr) { int wordIdx = 0; - DefineLineInformation; int depth = TclGetStackDepth(envPtr); TclEmitInstInt4(INST_EXPAND_START, envPtr->currStackDepth, envPtr); @@ -1726,8 +1513,6 @@ CompileExpanded( for (; wordIdx < numWords; wordIdx++, tokenPtr = TokenAfter(tokenPtr)) { int objIdx; - SetLineInformation(wordIdx); - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { CompileTokens(envPtr, tokenPtr, interp); if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) { @@ -1738,10 +1523,6 @@ CompileExpanded( objIdx = TclRegisterNewLiteral(envPtr, tokenPtr[1].start, tokenPtr[1].size); - if (envPtr->clNext) { - TclContinuationsEnterDerived(TclFetchLiteral(envPtr, objIdx), - tokenPtr[1].start - envPtr->source, envPtr->clNext); - } TclEmitPush(objIdx, envPtr); } @@ -1771,30 +1552,20 @@ CompileCmdCompileProc( Command *cmdPtr, CompileEnv *envPtr) { - DefineLineInformation; int depth = TclGetStackDepth(envPtr); - + int savedNumCommands = envPtr->numCommands; + if (TCL_OK == TclAttemptCompileProc(interp, parsePtr, 1, cmdPtr, envPtr)) { TclCheckStackDepth(depth+1, envPtr); return TCL_OK; } /* - * Throw out any line information generated by the failed compile attempt. - */ - - while (mapPtr->nuloc - 1 > eclIndex) { - mapPtr->nuloc--; - ckfree(mapPtr->loc[mapPtr->nuloc].line); - mapPtr->loc[mapPtr->nuloc].line = NULL; - } - - /* * Reset the index of next command. Toss out any from failed nested * partial compiles. */ - envPtr->numCommands = mapPtr->nuloc; + envPtr->numCommands = savedNumCommands; return TCL_ERROR; } @@ -1806,14 +1577,10 @@ CompileCommandTokens( { Interp *iPtr = (Interp *) interp; Tcl_Token *tokenPtr = parsePtr->tokenPtr; - ExtCmdLoc *eclPtr = envPtr->extCmdMapPtr; Tcl_Obj *cmdObj = Tcl_NewObj(); Command *cmdPtr = NULL; int code = TCL_ERROR; int cmdKnown, expand = -1; - int *wlines, wlineat; - int cmdLine = envPtr->line; - int *clNext = envPtr->clNext; int cmdIdx = envPtr->numCommands; int startCodeOffset = envPtr->codeNext - envPtr->codeStart; int depth = TclGetStackDepth(envPtr); @@ -1826,22 +1593,6 @@ CompileCommandTokens( EnterCmdStartData(envPtr, cmdIdx, parsePtr->commandStart - envPtr->source, startCodeOffset); - /* - * TIP #280. Scan the words and compute the extended location information. - * The map first contain full per-word line information for use by the - * compiler. This is later replaced by a reduced form which signals - * non-literal words, stored in 'wlines'. - */ - - EnterCmdWordData(eclPtr, parsePtr->commandStart - envPtr->source, - parsePtr->tokenPtr, parsePtr->commandStart, - parsePtr->commandSize, parsePtr->numWords, cmdLine, - clNext, &wlines, envPtr); - wlineat = eclPtr->nuloc - 1; - - envPtr->line = eclPtr->loc[wlineat].line[0]; - envPtr->clNext = eclPtr->loc[wlineat].next[0]; - /* Do we know the command word? */ Tcl_IncrRefCount(cmdObj); tokenPtr = parsePtr->tokenPtr; @@ -1896,18 +1647,6 @@ CompileCommandTokens( (envPtr->codeNext-envPtr->codeStart) - startCodeOffset); TclEmitOpcode(INST_POP, envPtr); - /* - * TIP #280: Free full form of per-word line data and insert the reduced - * form now - */ - - envPtr->line = cmdLine; - envPtr->clNext = clNext; - ckfree(eclPtr->loc[wlineat].line); - ckfree(eclPtr->loc[wlineat].next); - eclPtr->loc[wlineat].line = wlines; - eclPtr->loc[wlineat].next = NULL; - TclCheckStackDepth(depth, envPtr); return cmdIdx; } @@ -1967,15 +1706,6 @@ TclCompileScript( #endif /* - * TIP #280: Count newlines before the command start. - * (See test info-30.33). - */ - - TclAdvanceLines(&envPtr->line, p, parse.commandStart); - TclAdvanceContinuations(&envPtr->line, &envPtr->clNext, - parse.commandStart - envPtr->source); - - /* * Advance parser to the next command in the script. */ @@ -2005,13 +1735,6 @@ TclCompileScript( lastCmdIdx = CompileCommandTokens(interp, &parse, envPtr); - /* - * TIP #280: Track lines in the just compiled command. - */ - - TclAdvanceLines(&envPtr->line, parse.commandStart, p); - TclAdvanceContinuations(&envPtr->line, &envPtr->clNext, - p - envPtr->source); Tcl_FreeParse(&parse); } @@ -2110,9 +1833,6 @@ TclCompileVarSubst( * Emit instructions to load the variable. */ - TclAdvanceLines(&envPtr->line, tokenPtr[1].start, - tokenPtr[1].start + tokenPtr[1].size); - if (tokenPtr->numComponents == 1) { if (localVar < 0) { TclEmitOpcode(INST_LOAD_STK, envPtr); @@ -2190,8 +1910,6 @@ TclCompileTokens( switch (tokenPtr->type) { case TCL_TOKEN_TEXT: TclDStringAppendToken(&textBuffer, tokenPtr); - TclAdvanceLines(&envPtr->line, tokenPtr->start, - tokenPtr->start + tokenPtr->size); break; case TCL_TOKEN_BS: @@ -2243,17 +1961,10 @@ TclCompileTokens( numObjsToConcat++; Tcl_DStringFree(&textBuffer); - if (numCL) { - TclContinuationsEnter(TclFetchLiteral(envPtr, literal), - numCL, clPosition); - } - numCL = 0; } - envPtr->line += adjust; TclCompileScript(interp, tokenPtr->start+1, tokenPtr->size-2, envPtr); - envPtr->line -= adjust; numObjsToConcat++; break; @@ -2292,11 +2003,6 @@ TclCompileTokens( TclEmitPush(literal, envPtr); numObjsToConcat++; - if (numCL) { - TclContinuationsEnter(TclFetchLiteral(envPtr, literal), - numCL, clPosition); - } - numCL = 0; } /* @@ -2534,7 +2240,7 @@ TclInitByteCodeObj( #endif int numLitObjects = envPtr->literalArrayNext; Namespace *namespacePtr; - int i, isNew; + int i; Interp *iPtr; if (envPtr->iPtr == NULL) { @@ -2670,15 +2376,6 @@ TclInitByteCodeObj( objPtr->internalRep.twoPtrValue.ptr1 = codePtr; objPtr->typePtr = &tclByteCodeType; - /* - * TIP #280. Associate the extended per-word line information with the - * byte code object (internal rep), for use with the bc compiler. - */ - - Tcl_SetHashValue(Tcl_CreateHashEntry(iPtr->lineBCPtr, codePtr, - &isNew), envPtr->extCmdMapPtr); - envPtr->extCmdMapPtr = NULL; - /* We've used up the CompileEnv. Mark as uninitialized. */ envPtr->iPtr = NULL; @@ -2991,86 +2688,6 @@ EnterCmdExtentData( /* *---------------------------------------------------------------------- - * TIP #280 - * - * EnterCmdWordData -- - * - * Registers the lines for the words of a command. This information is - * used at runtime by 'info frame'. - * - * Results: - * None. - * - * Side effects: - * Inserts word location information into the compilation environment - * envPtr for the command at index cmdIndex. The compilation - * environment's ExtCmdLoc.ECL array is grown if necessary. - * - *---------------------------------------------------------------------- - */ - -static void -EnterCmdWordData( - ExtCmdLoc *eclPtr, /* Points to the map environment structure in - * which to enter command location - * information. */ - int srcOffset, /* Offset of first char of the command. */ - Tcl_Token *tokenPtr, - const char *cmd, - int len, - int numWords, - int line, - int *clNext, - int **wlines, - CompileEnv *envPtr) -{ - ECL *ePtr; - const char *last; - int wordIdx, wordLine, *wwlines, *wordNext; - - if (eclPtr->nuloc >= eclPtr->nloc) { - /* - * Expand the ECL array by allocating more storage from the heap. The - * currently allocated ECL entries are stored from eclPtr->loc[0] up - * to eclPtr->loc[eclPtr->nuloc-1] (inclusive). - */ - - size_t currElems = eclPtr->nloc; - size_t newElems = (currElems ? 2*currElems : 1); - size_t newBytes = newElems * sizeof(ECL); - - eclPtr->loc = ckrealloc(eclPtr->loc, newBytes); - eclPtr->nloc = newElems; - } - - ePtr = &eclPtr->loc[eclPtr->nuloc]; - ePtr->srcOffset = srcOffset; - ePtr->line = ckalloc(numWords * sizeof(int)); - ePtr->next = ckalloc(numWords * sizeof(int *)); - ePtr->nline = numWords; - wwlines = ckalloc(numWords * sizeof(int)); - - last = cmd; - wordLine = line; - wordNext = clNext; - for (wordIdx=0 ; wordIdx<numWords; - wordIdx++, tokenPtr += tokenPtr->numComponents + 1) { - TclAdvanceLines(&wordLine, last, tokenPtr->start); - TclAdvanceContinuations(&wordLine, &wordNext, - tokenPtr->start - envPtr->source); - wwlines[wordIdx] = - (TclWordKnownAtCompileTime(tokenPtr, NULL) ? wordLine : -1); - ePtr->line[wordIdx] = wordLine; - ePtr->next[wordIdx] = wordNext; - last = tokenPtr->start; - } - - *wlines = wwlines; - eclPtr->nuloc ++; -} - -/* - *---------------------------------------------------------------------- * * TclCreateExceptRange -- * diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 371a254..fadc9e3 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -133,39 +133,6 @@ typedef struct CmdLocation { } CmdLocation; /* - * TIP #280 - * Structure to record additional location information for byte code. This - * information is internal and not saved. i.e. tbcload'ed code will not have - * this information. It records the lines for all words of all commands found - * in the byte code. The association with a ByteCode structure BC is done - * through the 'lineBCPtr' HashTable in Interp, keyed by the address of BC. - * Also recorded is information coming from the context, i.e. type of the - * frame and associated information, like the path of a sourced file. - */ - -typedef struct ECL { - int srcOffset; /* Command location to find the entry. */ - int nline; /* Number of words in the command */ - int *line; /* Line information for all words in the - * command. */ - int **next; /* Transient information used by the compiler - * for tracking of hidden continuation - * lines. */ -} ECL; - -typedef struct ExtCmdLoc { - int type; /* Context type. */ - int start; /* Starting line for compiled script. Needed - * for the extended recompile check in - * tclCompileObj. */ - Tcl_Obj *path; /* Path of the sourced file the command is - * in. */ - ECL *loc; /* Command word locations (lines). */ - int nloc; /* Number of allocated entries in 'loc'. */ - int nuloc; /* Number of used entries in 'loc'. */ -} ExtCmdLoc; - -/* * CompileProcs need the ability to record information during compilation that * can be used by bytecode instructions during execution. The AuxData * structure provides this "auxiliary data" mechanism. An arbitrary number of @@ -318,15 +285,6 @@ typedef struct CompileEnv { /* Initial storage for cmd location map. */ AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE]; /* Initial storage for aux data array. */ - /* TIP #280 */ - ExtCmdLoc *extCmdMapPtr; /* Extended command location information for - * 'info frame'. */ - int line; /* First line of the script, based on the - * invoking context, then the line of the - * command currently compiled. */ - int *clNext; /* If not NULL, it refers to the next slot in - * clLoc to check for an invisible - * continuation line. */ } CompileEnv; /* @@ -952,8 +910,7 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRInterpCoroutine; *---------------------------------------------------------------- */ -MODULE_SCOPE ByteCode * TclCompileObj(Tcl_Interp *interp, Tcl_Obj *objPtr, - const CmdFrame *invoker, int word); +MODULE_SCOPE ByteCode * TclCompileObj(Tcl_Interp *interp, Tcl_Obj *objPtr); /* *---------------------------------------------------------------- @@ -1013,7 +970,7 @@ MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr, CompileEnv *envPtr); MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp, CompileEnv *envPtr, const char *string, - int numBytes, const CmdFrame *invoker, int word); + int numBytes); MODULE_SCOPE void TclInitJumpFixupArray(JumpFixupArray *fixupArrayPtr); MODULE_SCOPE void TclInitLiteralTable(LiteralTable *tablePtr); @@ -1065,8 +1022,6 @@ MODULE_SCOPE void TclLogCommandInfo(Tcl_Interp *interp, const char *script, const char *command, int length, const unsigned char *pc, Tcl_Obj **tosPtr); -MODULE_SCOPE Tcl_Obj *TclGetInnerContext(Tcl_Interp *interp, - const unsigned char *pc, Tcl_Obj **tosPtr); MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst); MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, register Tcl_Interp *interp, int objc, @@ -1437,7 +1392,6 @@ TclGetInt4AtPtr(const unsigned char *p) */ #define BODY(tokenPtr, word) \ - SetLineInformation((word)); \ TclCompileCmdWord(interp, (tokenPtr)+1, (tokenPtr)->numComponents, \ envPtr) @@ -1550,36 +1504,14 @@ TclGetInt4AtPtr(const unsigned char *p) * Tcl_Interp *interp, int word); */ -#define CompileWord(envPtr, tokenPtr, interp, word) \ +#define CompileWord(envPtr, tokenPtr, interp) \ if ((tokenPtr)->type == TCL_TOKEN_SIMPLE_WORD) { \ PushLiteral((envPtr), (tokenPtr)[1].start, (tokenPtr)[1].size); \ } else { \ - SetLineInformation((word)); \ CompileTokens((envPtr), (tokenPtr), (interp)); \ } /* - * TIP #280: Remember the per-word line information of the current command. An - * index is used instead of a pointer as recursive compilation may reallocate, - * i.e. move, the array. This is also the reason to save the nuloc now, it may - * change during the course of the function. - * - * Macro to encapsulate the variable definition and setup. - */ - -#define DefineLineInformation \ - ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \ - int eclIndex = mapPtr->nuloc - 1 - -#define SetLineInformation(word) \ - envPtr->line = mapPtr->loc[eclIndex].line[(word)]; \ - envPtr->clNext = mapPtr->loc[eclIndex].next[(word)] - -#define PushVarNameWord(i,v,e,f,l,sc,word) \ - SetLineInformation(word); \ - TclPushVarName(i,v,e,f,l,sc) - -/* * Often want to issue one of two versions of an instruction based on whether * the argument will fit in a single byte or not. This makes it much clearer. */ diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index c8474e6..4e44e82 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -2357,7 +2357,6 @@ DictForNRCmd( int objc, Tcl_Obj *const *objv) { - Interp *iPtr = (Interp *) interp; Tcl_Obj *scriptObj, *keyVarObj, *valueVarObj; Tcl_Obj **varv, *keyObj, *valueObj; Tcl_DictSearch *searchPtr; @@ -2430,7 +2429,7 @@ DictForNRCmd( TclNRAddCallback(interp, DictForLoopCallback, searchPtr, keyVarObj, valueVarObj, scriptObj); - return TclNREvalObjEx(interp, scriptObj, 0, iPtr->cmdFramePtr, 3); + return TclNREvalObjEx(interp, scriptObj, 0); /* * For unwinding everything on error. @@ -2451,7 +2450,6 @@ DictForLoopCallback( Tcl_Interp *interp, int result) { - Interp *iPtr = (Interp *) interp; Tcl_DictSearch *searchPtr = data[0]; Tcl_Obj *keyVarObj = data[1]; Tcl_Obj *valueVarObj = data[2]; @@ -2512,7 +2510,7 @@ DictForLoopCallback( TclNRAddCallback(interp, DictForLoopCallback, searchPtr, keyVarObj, valueVarObj, scriptObj); - return TclNREvalObjEx(interp, scriptObj, 0, iPtr->cmdFramePtr, 3); + return TclNREvalObjEx(interp, scriptObj, 0); /* * For unwinding everything once the iterating is done. @@ -2552,7 +2550,6 @@ DictMapNRCmd( int objc, Tcl_Obj *const *objv) { - Interp *iPtr = (Interp *) interp; Tcl_Obj **varv, *keyObj, *valueObj; DictMapStorage *storagePtr; int varc, done; @@ -2632,8 +2629,7 @@ DictMapNRCmd( */ TclNRAddCallback(interp, DictMapLoopCallback, storagePtr, NULL,NULL,NULL); - return TclNREvalObjEx(interp, storagePtr->scriptObj, 0, - iPtr->cmdFramePtr, 3); + return TclNREvalObjEx(interp, storagePtr->scriptObj, 0); /* * For unwinding everything on error. @@ -2655,7 +2651,6 @@ DictMapLoopCallback( Tcl_Interp *interp, int result) { - Interp *iPtr = (Interp *) interp; DictMapStorage *storagePtr = data[0]; Tcl_Obj *keyObj, *valueObj; int done; @@ -2722,8 +2717,7 @@ DictMapLoopCallback( */ TclNRAddCallback(interp, DictMapLoopCallback, storagePtr, NULL,NULL,NULL); - return TclNREvalObjEx(interp, storagePtr->scriptObj, 0, - iPtr->cmdFramePtr, 3); + return TclNREvalObjEx(interp, storagePtr->scriptObj, 0); /* * For unwinding everything once the iterating is done. @@ -2883,7 +2877,6 @@ DictFilterCmd( int objc, Tcl_Obj *const *objv) { - Interp *iPtr = (Interp *) interp; static const char *const filters[] = { "key", "script", "value", NULL }; @@ -3068,7 +3061,7 @@ DictFilterCmd( * TIP #280. Make invoking context available to loop body. */ - result = TclEvalObjEx(interp, scriptObj, 0, iPtr->cmdFramePtr, 4); + result = Tcl_EvalObjEx(interp, scriptObj, 0); switch (result) { case TCL_OK: boolObj = Tcl_GetObjResult(interp); @@ -3167,7 +3160,6 @@ DictUpdateCmd( int objc, Tcl_Obj *const *objv) { - Interp *iPtr = (Interp *) interp; Tcl_Obj *dictPtr, *objPtr; int i, dummy; @@ -3211,7 +3203,7 @@ DictUpdateCmd( Tcl_IncrRefCount(objv[1]); TclNRAddCallback(interp, FinalizeDictUpdate, objv[1], objPtr, NULL,NULL); - return TclNREvalObjEx(interp, objv[objc-1], 0, iPtr->cmdFramePtr, objc-1); + return TclNREvalObjEx(interp, objv[objc-1], 0); } static int @@ -3325,7 +3317,6 @@ DictWithCmd( int objc, Tcl_Obj *const *objv) { - Interp *iPtr = (Interp *) interp; Tcl_Obj *dictPtr, *keysPtr, *pathPtr; if (objc < 3) { @@ -3362,7 +3353,7 @@ DictWithCmd( TclNRAddCallback(interp, FinalizeDictWith, objv[1], keysPtr, pathPtr, NULL); - return TclNREvalObjEx(interp, objv[objc-1], 0, iPtr->cmdFramePtr, objc-1); + return TclNREvalObjEx(interp, objv[objc-1], 0); } static int diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 8190100..819ca77 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -595,124 +595,6 @@ FormatInstruction( /* *---------------------------------------------------------------------- * - * TclGetInnerContext -- - * - * If possible, returns a list capturing the inner context. Otherwise - * return NULL. - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj * -TclGetInnerContext( - Tcl_Interp *interp, - const unsigned char *pc, - Tcl_Obj **tosPtr) -{ - int objc = 0, off = 0; - Tcl_Obj *result; - Interp *iPtr = (Interp *) interp; - - switch (*pc) { - case INST_STR_LEN: - case INST_LNOT: - case INST_BITNOT: - case INST_UMINUS: - case INST_UPLUS: - case INST_TRY_CVT_TO_NUMERIC: - case INST_EXPAND_STKTOP: - case INST_EXPR_STK: - objc = 1; - break; - - case INST_LIST_IN: - case INST_LIST_NOT_IN: /* Basic list containment operators. */ - case INST_STR_EQ: - case INST_STR_NEQ: /* String (in)equality check */ - case INST_STR_CMP: /* String compare. */ - case INST_STR_INDEX: - case INST_STR_MATCH: - case INST_REGEXP: - case INST_EQ: - case INST_NEQ: - case INST_LT: - case INST_GT: - case INST_LE: - case INST_GE: - case INST_MOD: - case INST_LSHIFT: - case INST_RSHIFT: - case INST_BITOR: - case INST_BITXOR: - case INST_BITAND: - case INST_EXPON: - case INST_ADD: - case INST_SUB: - case INST_DIV: - case INST_MULT: - objc = 2; - break; - - case INST_RETURN_STK: - /* early pop. TODO: dig out opt dict too :/ */ - objc = 1; - break; - - case INST_SYNTAX: - case INST_RETURN_IMM: - objc = 2; - break; - - case INST_INVOKE_STK4: - objc = TclGetUInt4AtPtr(pc+1); - break; - - case INST_INVOKE_STK1: - objc = TclGetUInt1AtPtr(pc+1); - break; - } - - result = iPtr->innerContext; - if (Tcl_IsShared(result)) { - Tcl_DecrRefCount(result); - iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL); - Tcl_IncrRefCount(result); - } else { - int len; - - /* - * Reset while keeping the list intrep as much as possible. - */ - - Tcl_ListObjLength(interp, result, &len); - Tcl_ListObjReplace(interp, result, 0, len, 0, NULL); - } - Tcl_ListObjAppendElement(NULL, result, TclNewInstNameObj(*pc)); - - for (; objc>0 ; objc--) { - Tcl_Obj *objPtr; - - objPtr = tosPtr[1 - objc + off]; - if (!objPtr) { - Tcl_Panic("InnerContext: bad tos -- appending null object"); - } - if ((objPtr->refCount<=0) -#ifdef TCL_MEM_DEBUG - || (objPtr->refCount==0x61616161) -#endif - ) { - Tcl_Panic("InnerContext: bad tos -- appending freed object %p", - objPtr); - } - Tcl_ListObjAppendElement(NULL, result, objPtr); - } - - return result; -} - -/* - *---------------------------------------------------------------------- - * * TclNewInstNameObj -- * * Creates a new InstName Tcl_Obj based on the given instruction diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 8f7d1a2..959ff71 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -1902,7 +1902,7 @@ NsEnsembleImplementationCmdNR( */ TclSkipTailcall(interp); - return TclNREvalObjEx(interp, copyPtr, TCL_EVAL_INVOKE, NULL,INT_MIN); + return TclNREvalObjEx(interp, copyPtr, TCL_EVAL_INVOKE); } unknownOrAmbiguousSubcommand: @@ -2749,7 +2749,6 @@ TclCompileEnsemble( int ourResult = TCL_ERROR; unsigned numBytes; const char *word; - DefineLineInformation; Tcl_IncrRefCount(replaced); if (parsePtr->numWords < depth + 1) { @@ -3009,23 +3008,6 @@ TclCompileEnsemble( } /* - * Throw out any line information generated by the failed compile attempt. - */ - - while (mapPtr->nuloc - 1 > eclIndex) { - mapPtr->nuloc--; - ckfree(mapPtr->loc[mapPtr->nuloc].line); - mapPtr->loc[mapPtr->nuloc].line = NULL; - } - - /* - * Reset the index of next command. Toss out any from failed nested - * partial compiles. - */ - - envPtr->numCommands = mapPtr->nuloc; - - /* * Failed to do a full compile for some reason. Try to do a direct invoke * instead of going through the ensemble lookup process again. */ @@ -3082,7 +3064,6 @@ TclAttemptCompileProc( Tcl_Token *saveTokenPtr = parsePtr->tokenPtr; int savedStackDepth = envPtr->currStackDepth; unsigned savedCodeNext = envPtr->codeNext - envPtr->codeStart; - DefineLineInformation; if (cmdPtr->compileProc == NULL) { return TCL_ERROR; @@ -3101,26 +3082,11 @@ TclAttemptCompileProc( parsePtr->numWords -= (depth - 1); /* - * Shift the line information arrays to account for different word - * index values. - */ - - mapPtr->loc[eclIndex].line += (depth - 1); - mapPtr->loc[eclIndex].next += (depth - 1); - - /* * Hand off compilation to the subcommand compiler. At last! */ result = cmdPtr->compileProc(interp, parsePtr, cmdPtr, envPtr); - /* - * Undo the shift. - */ - - mapPtr->loc[eclIndex].line -= (depth - 1); - mapPtr->loc[eclIndex].next -= (depth - 1); - parsePtr->numWords += (depth - 1); parsePtr->tokenPtr = saveTokenPtr; @@ -3172,7 +3138,6 @@ CompileToInvokedCommand( Tcl_Obj *objPtr, **words; char *bytes; int length, i, numWords, cmdLit; - DefineLineInformation; /* * Push the words of the command. Take care; the command words may be @@ -3189,17 +3154,9 @@ CompileToInvokedCommand( continue; } - SetLineInformation(i); if (tokPtr->type == TCL_TOKEN_SIMPLE_WORD) { int literal = TclRegisterNewLiteral(envPtr, tokPtr[1].start, tokPtr[1].size); - - if (envPtr->clNext) { - TclContinuationsEnterDerived( - TclFetchLiteral(envPtr, literal), - tokPtr[1].start - envPtr->source, - envPtr->clNext); - } TclEmitPush(literal, envPtr); } else { CompileTokens(envPtr, tokPtr, interp); diff --git a/generic/tclExecute.c b/generic/tclExecute.c index fc1863b..eb66bce 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -127,7 +127,7 @@ typedef struct expandAux { typedef struct TEBCdata { ByteCode *codePtr; - CmdFrame cmdFrame; + Tcl_Obj *srcPtr; void *stack[1]; } TEBCdata; @@ -713,7 +713,7 @@ static Tcl_Obj * ExecuteExtendedUnaryMathOp(int opcode, static void FreeExprCodeInternalRep(Tcl_Obj *objPtr); static const char * GetSrcInfoForPc(const unsigned char *pc, ByteCode *codePtr, int *lengthPtr, - const unsigned char **pcBeg, int *cmdIdxPtr); + const unsigned char **pcBeg); static void GetISCInfoForPc(const unsigned char *pc, ByteCode *codePtr, CmdLocation *cmdLocPtr); static Tcl_Obj ** GrowEvaluationStack(ExecEnv *eePtr, int growth, @@ -795,6 +795,38 @@ ReleaseDictIterator( objPtr->typePtr = NULL; } +static void UpdateStringOfBcSource(Tcl_Obj *objPtr); + +static const Tcl_ObjType bcSourceType = { + "bcSource", /* name */ + NULL, /* freeIntRepProc */ + NULL, /* dupIntRepProc */ + UpdateStringOfBcSource, /* updateStringProc */ + NULL /* setFromAnyProc */ +}; + +static void +UpdateStringOfBcSource( + Tcl_Obj *objPtr) +{ + int len; + const char *bytes; + unsigned char *pc = objPtr->internalRep.twoPtrValue.ptr1; + ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr2; + + bytes = GetSrcInfoForPc(pc, codePtr, &len, NULL); + if (bytes) { + objPtr->bytes = (char *) ckalloc((unsigned) len + 1); + memcpy(objPtr->bytes, bytes, len); + objPtr->bytes[len] = '\0'; + objPtr->length = len; + } else { + /* should not happen ... but it does in test execute-11.2 */ + objPtr->bytes = tclEmptyStringRep; + objPtr->length = 0; + } +} + /* *---------------------------------------------------------------------- * @@ -1503,7 +1535,7 @@ CompileExprObj( int length; const char *string = TclGetStringFromObj(objPtr, &length); - TclInitCompileEnv(interp, &compEnv, string, length, NULL, 0); + TclInitCompileEnv(interp, &compEnv, string, length); TclCompileExpr(interp, string, length, &compEnv, 0); /* @@ -1625,9 +1657,7 @@ FreeExprCodeInternalRep( ByteCode * TclCompileObj( Tcl_Interp *interp, - Tcl_Obj *objPtr, - const CmdFrame *invoker, - int word) + Tcl_Obj *objPtr) { register Interp *iPtr = (Interp *) interp; register ByteCode *codePtr; /* Tcl Internal type of bytecode. */ @@ -1682,93 +1712,7 @@ TclCompileObj( goto recompileObj; } - /* - * #280. - * Literal sharing fix. This part of the fix is not required by 8.4 - * nor 8.5, because they eval-direct any literals, so just saving the - * argument locations per command in bytecode is enough, embedded - * 'eval' commands, etc. get the correct information. - * - * But in 8.6 all the embedded script are compiled, and the resulting - * bytecode stored in the literal. Now the shared literal has bytecode - * with location data for _one_ particular location this literal is - * found at. If we get executed from a different location the bytecode - * has to be recompiled to get the correct locations. Not doing this - * will execute the saved bytecode with data for a different location, - * causing 'info frame' to point to the wrong place in the sources. - * - * Future optimizations ... - * (1) Save the location data (ExtCmdLoc) keyed by start line. In that - * case we recompile once per location of the literal, but not - * continously, because the moment we have all locations we do not - * need to recompile any longer. - * - * (2) Alternative: Do not recompile, tell the execution engine the - * offset between saved starting line and actual one. Then modify - * the users to adjust the locations they have by this offset. - * - * (3) Alternative 2: Do not fully recompile, adjust just the location - * information. - */ - - if (invoker == NULL) { - return codePtr; - } else { - Tcl_HashEntry *hePtr = - Tcl_FindHashEntry(iPtr->lineBCPtr, codePtr); - ExtCmdLoc *eclPtr; - CmdFrame *ctxCopyPtr; - int redo; - - if (!hePtr) { - return codePtr; - } - - eclPtr = Tcl_GetHashValue(hePtr); - redo = 0; - ctxCopyPtr = TclStackAlloc(interp, sizeof(CmdFrame)); - *ctxCopyPtr = *invoker; - - if (invoker->type == TCL_LOCATION_BC) { - /* - * Note: Type BC => ctx.data.eval.path is not used. - * ctx.data.tebc.codePtr used instead - */ - - TclGetSrcInfoForPc(ctxCopyPtr); - if (ctxCopyPtr->type == TCL_LOCATION_SOURCE) { - /* - * The reference made by 'TclGetSrcInfoForPc' is dead. - */ - - Tcl_DecrRefCount(ctxCopyPtr->data.eval.path); - ctxCopyPtr->data.eval.path = NULL; - } - } - - if (word < ctxCopyPtr->nline) { - /* - * Note: We do not care if the line[word] is -1. This is a - * difference and requires a recompile (location changed from - * absolute to relative, literal is used fixed and through - * variable) - * - * Example: - * test info-32.0 using literal of info-24.8 - * (dict with ... vs set body ...). - */ - - redo = ((eclPtr->type == TCL_LOCATION_SOURCE) - && (eclPtr->start != ctxCopyPtr->line[word])) - || ((eclPtr->type == TCL_LOCATION_BC) - && (ctxCopyPtr->type == TCL_LOCATION_SOURCE)); - } - - TclStackFree(interp, ctxCopyPtr); - if (!redo) { - return codePtr; - } - } + return codePtr; } recompileObj: @@ -1781,10 +1725,7 @@ TclCompileObj( * information. */ - iPtr->invokeCmdFramePtr = invoker; - iPtr->invokeWord = word; TclSetByteCodeFromAny(interp, objPtr, NULL, NULL); - iPtr->invokeCmdFramePtr = NULL; codePtr = objPtr->internalRep.twoPtrValue.ptr1; if (iPtr->varFramePtr->localCachePtr) { codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr; @@ -1922,41 +1863,6 @@ TclIncrObj( /* *---------------------------------------------------------------------- * - * ArgumentBCEnter -- - * - * This is a helper for TclNRExecuteByteCode/TEBCresume that encapsulates - * a code sequence that is fairly common in the code but *not* commonly - * called. - * - * Results: - * None - * - * Side effects: - * May register information about the bytecode in the command frame. - * - *---------------------------------------------------------------------- - */ - -static void -ArgumentBCEnter( - Tcl_Interp *interp, - ByteCode *codePtr, - TEBCdata *tdPtr, - const unsigned char *pc, - int objc, - Tcl_Obj **objv) -{ - int cmd; - - if (GetSrcInfoForPc(pc, codePtr, NULL, NULL, &cmd)) { - TclArgumentBCEnter(interp, objv, objc, codePtr, &tdPtr->cmdFrame, cmd, - pc - codePtr->codeStart); - } -} - -/* - *---------------------------------------------------------------------- - * * TclNRExecuteByteCode -- * * This procedure executes the instructions of a ByteCode structure. It @@ -1972,9 +1878,9 @@ ArgumentBCEnter( * *---------------------------------------------------------------------- */ -#define bcFramePtr (&TD->cmdFrame) #define initTosPtr ((Tcl_Obj **) (&TD->stack[-1])) #define esPtr (iPtr->execEnvPtr->execStackPtr) +#define srcPtr (TD->srcPtr) int TclNRExecuteByteCode( @@ -1991,36 +1897,22 @@ TclNRExecuteByteCode( /* * Reserve the stack, setup the TEBCdataPtr (TD) and CallFrame * - * The execution uses a unified stack: first a TEBCdata, immediately - * above it a CmdFrame, then the execution stack. - * - * Make sure the execution stack is large enough to execute this - * ByteCode. + * The execution uses a unified stack: first a TEBCdata, then the + * execution stack. Make sure the execution stack is large enough to + * execute this ByteCode. */ TD = (TEBCdata *) GrowEvaluationStack(iPtr->execEnvPtr, numWords, 0); + esPtr->tosPtr = initTosPtr; - TD->codePtr = codePtr; + TD->codePtr = codePtr; - /* - * TIP #280: Initialize the frame. Do not push it yet: it will be pushed - * every time that we call out from this TD, popped when we return to it. - */ - - bcFramePtr->type = ((codePtr->flags & TCL_BYTECODE_PRECOMPILED) - ? TCL_LOCATION_PREBC : TCL_LOCATION_BC); - bcFramePtr->level = (iPtr->cmdFramePtr ? iPtr->cmdFramePtr->level+1 : 1); - bcFramePtr->framePtr = iPtr->framePtr; - bcFramePtr->nextPtr = iPtr->cmdFramePtr; - bcFramePtr->nline = 0; - bcFramePtr->line = NULL; - bcFramePtr->litarg = NULL; - bcFramePtr->data.tebc.codePtr = codePtr; - bcFramePtr->data.tebc.pc = NULL; - bcFramePtr->cmdObj = NULL; - bcFramePtr->cmd = NULL; - bcFramePtr->len = 0; + srcPtr = Tcl_NewObj(); + TclInvalidateStringRep(srcPtr); + Tcl_IncrRefCount(srcPtr); + srcPtr->typePtr = &bcSourceType; + srcPtr->internalRep.twoPtrValue.ptr2 = codePtr; #ifdef TCL_COMPILE_STATS iPtr->stats.numExecutions++; @@ -2162,16 +2054,6 @@ TEBCresume( /* resume from invocation */ cmdLoc.numCodeBytes = -1; - 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(interp, bcFramePtr); - } if (iPtr->execEnvPtr->rewind) { result = TCL_ERROR; goto abnormalReturn; @@ -2501,17 +2383,6 @@ TEBCresume( yieldParameter = (PTR2INT(NULL)+1); /*==CORO_ACTIVATE_YIELDM*/ doYield: - /* TIP #280: Record the last piece of info needed by - * 'TclGetSrcInfoForPc', and push the frame. - */ - - bcFramePtr->data.tebc.pc = (char *) pc; - iPtr->cmdFramePtr = bcFramePtr; - - if (iPtr->flags & INTERP_DEBUG_FRAME) { - ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv); - } - pc++; cleanup = 1; TEBC_YIELD(); @@ -2858,8 +2729,6 @@ TEBCresume( case INST_EXPR_STK: { ByteCode *newCodePtr; - bcFramePtr->data.tebc.pc = (char *) pc; - iPtr->cmdFramePtr = bcFramePtr; DECACHE_STACK_INFO(); newCodePtr = CompileExprObj(interp, OBJ_AT_TOS); CACHE_STACK_INFO(); @@ -2875,13 +2744,10 @@ TEBCresume( instEvalStk: case INST_EVAL_STK: - bcFramePtr->data.tebc.pc = (char *) pc; - iPtr->cmdFramePtr = bcFramePtr; - cleanup = 1; pc += 1; TEBC_YIELD(); - return TclNREvalObjEx(interp, OBJ_AT_TOS, 0, NULL, 0); + return TclNREvalObjEx(interp, OBJ_AT_TOS, 0); case INST_INVOKE_EXPANDED: CLANG_ASSERT(expandList); @@ -2935,19 +2801,13 @@ TEBCresume( /* * Finally, let TclEvalObjv handle the command. * - * TIP #280: Record the last piece of info needed by - * 'TclGetSrcInfoForPc', and push the frame. */ - bcFramePtr->data.tebc.pc = (char *) pc; - iPtr->cmdFramePtr = bcFramePtr; - - if (iPtr->flags & INTERP_DEBUG_FRAME) { - ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv); - } - DECACHE_STACK_INFO(); + srcPtr->internalRep.twoPtrValue.ptr1 = (unsigned char *) pc; + iPtr->cmdSourcePtr = srcPtr; + pc += pcAdjustment; TEBC_YIELD(); @@ -3020,11 +2880,6 @@ TEBCresume( } objPtr = copyPtr; } - bcFramePtr->data.tebc.pc = (char *) pc; - iPtr->cmdFramePtr = bcFramePtr; - if (iPtr->flags & INTERP_DEBUG_FRAME) { - ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv); - } iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = opnd; iPtr->ensembleRewrite.numInsertedObjs = 1; @@ -3034,7 +2889,7 @@ TEBCresume( TclMarkTailcall(interp); TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL); - return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE, NULL, INT_MIN); + return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE); /* * ----------------------------------------------------------------- @@ -4745,13 +4600,6 @@ TEBCresume( } doInvokeNext: - bcFramePtr->data.tebc.pc = (char *) pc; - iPtr->cmdFramePtr = bcFramePtr; - - if (iPtr->flags & INTERP_DEBUG_FRAME) { - ArgumentBCEnter(interp, codePtr, TD, pc, opnd, objv); - } - pcAdjustment = 2; cleanup = opnd; DECACHE_STACK_INFO(); @@ -7675,7 +7523,7 @@ TEBCresume( if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) { const unsigned char *pcBeg; - bytes = GetSrcInfoForPc(pc, codePtr, &length, &pcBeg, NULL); + bytes = GetSrcInfoForPc(pc, codePtr, &length, &pcBeg); DECACHE_STACK_INFO(); TclLogCommandInfo(interp, codePtr->source, bytes, bytes ? length : 0, pcBeg, tosPtr); @@ -7812,10 +7660,10 @@ TEBCresume( CLANG_ASSERT(bcFramePtr); } - iPtr->cmdFramePtr = bcFramePtr->nextPtr; if (codePtr->refCount-- <= 1) { TclCleanupByteCode(codePtr); } + TclDecrRefCount(srcPtr); TclStackFree(interp, TD); /* free my stack */ return result; @@ -7887,6 +7735,7 @@ TEBCresume( #undef expandList #undef TCONST #undef esPtr +#undef srcPtr static int FinalizeOONext( @@ -9413,7 +9262,7 @@ ValidatePcAndStackTop( } if ((stackTop < 0) || (stackTop > stackUpperBound)) { int numChars; - const char *cmd = GetSrcInfoForPc(pc, codePtr, &numChars, NULL, NULL); + const char *cmd = GetSrcInfoForPc(pc, codePtr, &numChars, NULL); fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min 0, max %i)", stackTop, relativePc, stackUpperBound); @@ -9499,7 +9348,7 @@ IllegalExprOperandType( /* *---------------------------------------------------------------------- * - * TclGetSrcInfoForPc, GetSrcInfoForPc, TclGetSourceFromFrame -- + * GetSrcInfoForPc -- * * Given a program counter value, finds the closest command in the * bytecode code unit's CmdLocation array and returns information about @@ -9514,99 +9363,9 @@ IllegalExprOperandType( * no matching command is found, NULL is returned and *lengthPtr is * unchanged. * - * Side effects: - * The CmdFrame at *cfPtr is updated. - * *---------------------------------------------------------------------- */ -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) { - ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr; - - cfPtr->cmd = GetSrcInfoForPc((unsigned char *) - cfPtr->data.tebc.pc, codePtr, &cfPtr->len, NULL, NULL); - } - if (cfPtr->cmd) { - cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len); - } else { - cfPtr->cmdObj = Tcl_NewListObj(objc, objv); - } - Tcl_IncrRefCount(cfPtr->cmdObj); - } - return cfPtr->cmdObj; -} - -void -TclGetSrcInfoForPc( - CmdFrame *cfPtr) -{ - ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr; - - assert(cfPtr->type == TCL_LOCATION_BC); - - if (cfPtr->cmd == NULL) { - - cfPtr->cmd = GetSrcInfoForPc( - (unsigned char *) cfPtr->data.tebc.pc, codePtr, - &cfPtr->len, NULL, NULL); - } - - if (cfPtr->cmd != NULL) { - /* - * We now have the command. We can get the srcOffset back and from - * there find the list of word locations for this command. - */ - - ExtCmdLoc *eclPtr; - ECL *locPtr = NULL; - int srcOffset, i; - Interp *iPtr = (Interp *) *codePtr->interpHandle; - Tcl_HashEntry *hePtr = - Tcl_FindHashEntry(iPtr->lineBCPtr, codePtr); - - if (!hePtr) { - return; - } - - srcOffset = cfPtr->cmd - codePtr->source; - eclPtr = Tcl_GetHashValue(hePtr); - - for (i=0; i < eclPtr->nuloc; i++) { - if (eclPtr->loc[i].srcOffset == srcOffset) { - locPtr = eclPtr->loc+i; - break; - } - } - if (locPtr == NULL) { - Tcl_Panic("LocSearch failure"); - } - - cfPtr->line = locPtr->line; - cfPtr->nline = locPtr->nline; - cfPtr->type = eclPtr->type; - - if (eclPtr->type == TCL_LOCATION_SOURCE) { - cfPtr->data.eval.path = eclPtr->path; - Tcl_IncrRefCount(cfPtr->data.eval.path); - } - - /* - * Do not set cfPtr->data.eval.path NULL for non-SOURCE. Needed for - * cfPtr->data.tebc.codePtr. - */ - } -} - static const char * GetSrcInfoForPc( const unsigned char *pc, /* The program counter value for which to @@ -9618,12 +9377,9 @@ GetSrcInfoForPc( int *lengthPtr, /* If non-NULL, the location where the length * of the command's source should be stored. * If NULL, no length is stored. */ - const unsigned char **pcBeg,/* If non-NULL, the bytecode location + const unsigned char **pcBeg)/* If non-NULL, the bytecode location * where the current instruction starts. * If NULL; no pointer is stored. */ - int *cmdIdxPtr) /* If non-NULL, the location where the index - * of the command containing the pc should - * be stored. */ { register int pcOffset = (pc - codePtr->codeStart); int numCmds = codePtr->numCommands; @@ -9633,7 +9389,6 @@ GetSrcInfoForPc( int bestDist = INT_MAX; /* Distance of pc to best cmd's start pc. */ int bestSrcOffset = -1; /* Initialized to avoid compiler warning. */ int bestSrcLength = -1; /* Initialized to avoid compiler warning. */ - int bestCmdIdx = -1; /* The pc must point within the bytecode */ assert ((pcOffset >= 0) && (pcOffset < codePtr->numCodeBytes)); @@ -9699,7 +9454,6 @@ GetSrcInfoForPc( bestDist = dist; bestSrcOffset = srcOffset; bestSrcLength = srcLen; - bestCmdIdx = i; } } } @@ -9721,16 +9475,12 @@ GetSrcInfoForPc( *pcBeg = prev; } - if (bestDist == INT_MAX) { - return NULL; - } - if (lengthPtr != NULL) { *lengthPtr = bestSrcLength; } - if (cmdIdxPtr != NULL) { - *cmdIdxPtr = bestCmdIdx; + if (bestDist == INT_MAX) { + return NULL; } return (codePtr->source + bestSrcOffset); diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 1330c02..0df7088 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -1824,7 +1824,7 @@ Tcl_FSEvalFileEx( */ iPtr->evalFlags |= TCL_EVAL_FILE; - result = TclEvalEx(interp, string, length, 0, 1, NULL, string); + result = Tcl_EvalEx(interp, string, length, 0); /* * Now we have to be careful; the script may have changed the @@ -1962,7 +1962,7 @@ TclNREvalFile( iPtr->evalFlags |= TCL_EVAL_FILE; TclNRAddCallback(interp, EvalFileCallback, oldScriptFile, pathPtr, objPtr, NULL); - return TclNREvalObjEx(interp, objPtr, 0, NULL, INT_MIN); + return TclNREvalObjEx(interp, objPtr, 0); } static int diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 8213c9f..29cddb2 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -921,13 +921,12 @@ declare 231 { } # Bits and pieces of TIP#280's guts -declare 232 { - int TclEvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, - const CmdFrame *invoker, int word) -} -declare 233 { - void TclGetSrcInfoForPc(CmdFrame *contextPtr) -} +#declare 232 { +# int TclEvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags) +#} +#declare 233 { +# void TclGetSrcInfoForPc(CmdFrame *contextPtr) +#} # Exports for VarReform compat: Itcl, XOTcl like to peek into our varTables :( declare 234 { @@ -963,8 +962,7 @@ declare 240 { int TclNRRunCallbacks(Tcl_Interp *interp, int result) } declare 241 { - int TclNREvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, - const CmdFrame *invoker, int word) + int TclNREvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags) } declare 242 { int TclNREvalObjv(Tcl_Interp *interp, int objc, diff --git a/generic/tclInt.h b/generic/tclInt.h index 68f9556..46fb3a1 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1140,181 +1140,6 @@ typedef struct CallFrame { * TIP#257. */ /* - * TIP #280 - * The structure below defines a command frame. A command frame provides - * location information for all commands executing a tcl script (source, eval, - * uplevel, procedure bodies, ...). The runtime structure essentially contains - * the stack trace as it would be if the currently executing command were to - * throw an error. - * - * For commands where it makes sense it refers to the associated CallFrame as - * well. - * - * The structures are chained in a single list, with the top of the stack - * anchored in the Interp structure. - * - * Instances can be allocated on the C stack, or the heap, the former making - * cleanup a bit simpler. - */ - -typedef struct CmdFrame { - /* - * General data. Always available. - */ - - int type; /* Values see below. */ - int level; /* Number of frames in stack, prevent O(n) - * scan of list. */ - int *line; /* Lines the words of the command start on. */ - int nline; - CallFrame *framePtr; /* Procedure activation record, may be - * NULL. */ - struct CmdFrame *nextPtr; /* Link to calling frame. */ - /* - * Data needed for Eval vs TEBC - * - * EXECUTION CONTEXTS and usage of CmdFrame - * - * Field TEBC EvalEx - * ======= ==== ====== - * level yes yes - * type BC/PREBC SRC/EVAL - * line0 yes yes - * framePtr yes yes - * ======= ==== ====== - * - * ======= ==== ========= union data - * line1 - yes - * line3 - yes - * path - yes - * ------- ---- ------ - * codePtr yes - - * pc yes - - * ======= ==== ====== - * - * ======= ==== ========= union cmd - * str.cmd yes yes - * str.len yes yes - * ------- ---- ------ - */ - - union { - struct { - Tcl_Obj *path; /* Path of the sourced file the command is - * in. */ - } eval; - struct { - const void *codePtr;/* Byte code currently executed... */ - const char *pc; /* ... and instruction pointer. */ - } tebc; - } data; - Tcl_Obj *cmdObj; - const char *cmd; /* The executed command, if possible... */ - int len; /* ... and its length. */ - const struct CFWordBC *litarg; - /* Link to set of literal arguments which have - * ben pushed on the lineLABCPtr stack by - * TclArgumentBCEnter(). These will be removed - * by TclArgumentBCRelease. */ -} CmdFrame; - -typedef struct CFWord { - CmdFrame *framePtr; /* CmdFrame to access. */ - int word; /* Index of the word in the command. */ - int refCount; /* Number of times the word is on the - * stack. */ -} CFWord; - -typedef struct CFWordBC { - CmdFrame *framePtr; /* CmdFrame to access. */ - int pc; /* Instruction pointer of a command in - * ExtCmdLoc.loc[.] */ - int word; /* Index of word in - * ExtCmdLoc.loc[cmd]->line[.] */ - struct CFWordBC *prevPtr; /* Previous entry in stack for same Tcl_Obj. */ - struct CFWordBC *nextPtr; /* Next entry for same command call. See - * CmdFrame litarg field for the list start. */ - Tcl_Obj *obj; /* Back reference to hashtable key */ -} CFWordBC; - -/* - * Structure to record the locations of invisible continuation lines in - * literal scripts, as character offset from the beginning of the script. Both - * compiler and direct evaluator use this information to adjust their line - * counters when tracking through the script, because when it is invoked the - * continuation line marker as a whole has been removed already, meaning that - * the \n which was part of it is gone as well, breaking regular line - * tracking. - * - * These structures are allocated and filled by both the function - * TclSubstTokens() in the file "tclParse.c" and its caller TclEvalEx() in the - * file "tclBasic.c", and stored in the thread-global hashtable "lineCLPtr" in - * file "tclObj.c". They are used by the functions TclSetByteCodeFromAny() and - * TclCompileScript(), both found in the file "tclCompile.c". Their memory is - * released by the function TclFreeObj(), in the file "tclObj.c", and also by - * the function TclThreadFinalizeObjects(), in the same file. - */ - -#define CLL_END (-1) - -typedef struct ContLineLoc { - int num; /* Number of entries in loc, not counting the - * final -1 marker entry. */ - int loc[1]; /* Table of locations, as character offsets. - * The table is allocated as part of the - * structure, extending behind the nominal end - * of the structure. An entry containing the - * value -1 is put after the last location, as - * end-marker/sentinel. */ -} ContLineLoc; - -/* - * The following macros define the allowed values for the type field of the - * CmdFrame structure above. Some of the values occur only in the extended - * location data referenced via the 'baseLocPtr'. - * - * TCL_LOCATION_EVAL : Frame is for a script evaluated by EvalEx. - * TCL_LOCATION_BC : Frame is for bytecode. - * TCL_LOCATION_PREBC : Frame is for precompiled bytecode. - * TCL_LOCATION_SOURCE : Frame is for a script evaluated by EvalEx, from a - * sourced file. - * TCL_LOCATION_PROC : Frame is for bytecode of a procedure. - * - * A TCL_LOCATION_BC type in a frame can be overridden by _SOURCE and _PROC - * types, per the context of the byte code in execution. - */ - -#define TCL_LOCATION_EVAL (0) /* Location in a dynamic eval script. */ -#define TCL_LOCATION_BC (2) /* Location in byte code. */ -#define TCL_LOCATION_PREBC (3) /* Location in precompiled byte code, no - * location. */ -#define TCL_LOCATION_SOURCE (4) /* Location in a file. */ -#define TCL_LOCATION_PROC (5) /* Location in a dynamic proc. */ -#define TCL_LOCATION_LAST (6) /* Number of values in the enum. */ - -/* - * Structure passed to describe procedure-like "procedures" that are not - * procedures (e.g. a lambda) so that their details can be reported correctly - * by [info frame]. Contains a sub-structure for each extra field. - */ - -typedef Tcl_Obj * (GetFrameInfoValueProc)(ClientData clientData); -typedef struct { - const char *name; /* Name of this field. */ - GetFrameInfoValueProc *proc; /* Function to generate a Tcl_Obj* from the - * clientData, or just use the clientData - * directly (after casting) if NULL. */ - ClientData clientData; /* Context for above function, or Tcl_Obj* if - * proc field is NULL. */ -} ExtraFrameInfoField; -typedef struct { - int length; /* Length of array. */ - ExtraFrameInfoField fields[2]; - /* Really as long as necessary, but this is - * long enough for nearly anything. */ -} ExtraFrameInfo; - -/* *---------------------------------------------------------------- * Data structures and procedures related to TclHandles, which are a very * lightweight method of preserving enough information to determine if an @@ -1423,8 +1248,6 @@ typedef struct ExecStack { typedef struct CorContext { struct CallFrame *framePtr; struct CallFrame *varFramePtr; - struct CmdFrame *cmdFramePtr; /* See Interp.cmdFramePtr */ - Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ } CorContext; typedef struct CoroutineData { @@ -1992,54 +1815,6 @@ typedef struct Interp { * code returned by a channel operation. */ /* - * Source code origin information (TIP #280). - */ - - CmdFrame *cmdFramePtr; /* Points to the command frame containing the - * location information for the current - * command. */ - const CmdFrame *invokeCmdFramePtr; - /* Points to the command frame which is the - * invoking context of the bytecode compiler. - * NULL when the byte code compiler is not - * active. */ - int invokeWord; /* Index of the word in the command which - * is getting compiled. */ - Tcl_HashTable *linePBodyPtr;/* This table remembers for each statically - * defined procedure the location information - * for its body. It is keyed by the address of - * the Proc structure for a procedure. The - * values are "struct CmdFrame*". */ - Tcl_HashTable *lineBCPtr; /* This table remembers for each ByteCode - * object the location information for its - * body. It is keyed by the address of the - * Proc structure for a procedure. The values - * are "struct ExtCmdLoc*". (See - * tclCompile.h) */ - Tcl_HashTable *lineLABCPtr; - Tcl_HashTable *lineLAPtr; /* This table remembers for each argument of a - * command on the execution stack the index of - * the argument in the command, and the - * location data of the command. It is keyed - * by the address of the Tcl_Obj containing - * the argument. The values are "struct - * CFWord*" (See tclBasic.c). This allows - * commands like uplevel, eval, etc. to find - * location information for their arguments, - * if they are a proper literal argument to an - * invoking command. Alt view: An index to the - * CmdFrame stack keyed by command argument - * holders. */ - ContLineLoc *scriptCLLocPtr;/* This table points to the location data for - * invisible continuation lines in the script, - * if any. This pointer is set by the function - * TclEvalObjEx() in file "tclBasic.c", and - * used by function ...() in the same file. - * It does for the eval/direct path of script - * execution what CompileEnv.clLoc does for - * the bytecode compiler. - */ - /* * TIP #268. The currently active selection mode, i.e. the package require * preferences. */ @@ -2097,17 +1872,6 @@ typedef struct Interp { * (asyncCancelMsg not NULL), takes precedence * over the default error messages returned by * a script cancellation operation. */ - - /* - * TIP #348 IMPLEMENTATION - Substituted error stack - */ - Tcl_Obj *errorStack; /* [info errorstack] value (as a Tcl_Obj). */ - Tcl_Obj *upLiteral; /* "UP" literal for [info errorstack] */ - Tcl_Obj *callLiteral; /* "CALL" literal for [info errorstack] */ - Tcl_Obj *innerLiteral; /* "INNER" literal for [info errorstack] */ - Tcl_Obj *innerContext; /* cached list for fast reallocation */ - int resetErrorStack; /* controls cleaning up of ::errorStack */ - #ifdef TCL_COMPILE_STATS /* * Statistical information about the bytecode compiler and interpreter's @@ -2117,6 +1881,7 @@ typedef struct Interp { ByteCodeStats stats; /* Holds compilation and execution statistics * for this interpreter. */ #endif /* TCL_COMPILE_STATS */ + Tcl_Obj *cmdSourcePtr; /* Command source obj, used for command traces */ } Interp; /* @@ -2740,24 +2505,6 @@ MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp); MODULE_SCOPE void TclMarkTailcall(Tcl_Interp *interp); MODULE_SCOPE void TclSkipTailcall(Tcl_Interp *interp); -/* - * This structure holds the data for the various iteration callbacks used to - * NRE the 'for' and 'while' commands. We need a separate structure because we - * have more than the 4 client data entries we can provide directly thorugh - * the callback API. It is the 'word' information which puts us over the - * limit. It is needed because the loop body is argument 4 of 'for' and - * argument 2 of 'while'. Not providing the correct index confuses the #280 - * code. We TclSmallAlloc/Free this. - */ - -typedef struct ForIterData { - Tcl_Obj *cond; /* Loop condition expression. */ - Tcl_Obj *body; /* Loop body. */ - Tcl_Obj *next; /* Loop step script, NULL for 'while'. */ - const char *msg; /* Error message part. */ - int word; /* Index of the body script in the command */ -} ForIterData; - /* TIP #357 - Structure doing the bookkeeping of handles for Tcl_LoadFile * and Tcl_FindSymbol. This structure corresponds to an opaque * typedef in tcl.h */ @@ -2813,21 +2560,6 @@ MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr, const unsigned char *bytes, int len); MODULE_SCOPE int TclNREvalCmd(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); -MODULE_SCOPE void TclAdvanceContinuations(int *line, int **next, - int loc); -MODULE_SCOPE void TclAdvanceLines(int *line, const char *start, - const char *end); -MODULE_SCOPE void TclArgumentEnter(Tcl_Interp *interp, - Tcl_Obj *objv[], int objc, CmdFrame *cf); -MODULE_SCOPE void TclArgumentRelease(Tcl_Interp *interp, - Tcl_Obj *objv[], int objc); -MODULE_SCOPE void TclArgumentBCEnter(Tcl_Interp *interp, - Tcl_Obj *objv[], int objc, - void *codePtr, CmdFrame *cfPtr, int cmd, int pc); -MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp, - CmdFrame *cfPtr); -MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj, - CmdFrame **cfPtrPtr, int *wordPtr); MODULE_SCOPE int TclArraySet(Tcl_Interp *interp, Tcl_Obj *arrayNameObj, Tcl_Obj *arrayElemObj); MODULE_SCOPE double TclBignumToDouble(const mp_int *bignum); @@ -2844,13 +2576,6 @@ MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp, MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd; MODULE_SCOPE int TclClearRootEnsemble(ClientData data[], Tcl_Interp *interp, int result); -MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num, - int *loc); -MODULE_SCOPE void TclContinuationsEnterDerived(Tcl_Obj *objPtr, - int start, int *clNext); -MODULE_SCOPE ContLineLoc *TclContinuationsGet(Tcl_Obj *objPtr); -MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr, - Tcl_Obj *originObjPtr); MODULE_SCOPE int TclConvertElement(const char *src, int length, char *dst, int flags); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); @@ -2858,10 +2583,6 @@ MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, const char *dict, int dictLength, const char **elementPtr, const char **nextPtr, int *sizePtr, int *literalPtr); -/* TIP #280 - Modified token based evulation, with line information. */ -MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script, - int numBytes, int flags, int line, - int *clNextOuter, const char *outerScript); MODULE_SCOPE Tcl_ObjCmdProc TclFileAttrsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileCopyCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileDeleteCmd; @@ -2921,8 +2642,6 @@ 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 char * TclGetStringStorage(Tcl_Obj *objPtr, unsigned int *sizePtr); MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern, @@ -2936,7 +2655,6 @@ MODULE_SCOPE int TclInfoExistsCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TclInfoCoroutineCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE Tcl_Obj * TclInfoFrame(Tcl_Interp *interp, CmdFrame *framePtr); MODULE_SCOPE int TclInfoGlobalsCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TclInfoLocalsCmd(ClientData dummy, Tcl_Interp *interp, @@ -2965,9 +2683,6 @@ MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *argPtr); MODULE_SCOPE Tcl_Obj * TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, int indexCount, Tcl_Obj *const indexArray[]); -/* TIP #280 */ -MODULE_SCOPE void TclListLines(Tcl_Obj *listObj, int line, int n, - int *lines, Tcl_Obj *const *elems); MODULE_SCOPE Tcl_Obj * TclListObjCopy(Tcl_Interp *interp, Tcl_Obj *listPtr); MODULE_SCOPE Tcl_Obj * TclLsetList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *indexPtr, Tcl_Obj *valuePtr); @@ -2981,7 +2696,6 @@ MODULE_SCOPE int TclMaxListLength(const char *bytes, int numBytes, MODULE_SCOPE int TclMergeReturnOptions(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Tcl_Obj **optionsPtrPtr, int *codePtr, int *levelPtr); -MODULE_SCOPE Tcl_Obj * TclNoErrorStack(Tcl_Interp *interp, Tcl_Obj *options); MODULE_SCOPE int TclNokia770Doubles(void); MODULE_SCOPE void TclNsDecrRefCount(Namespace *nsPtr); MODULE_SCOPE void TclObjVarErrMsg(Tcl_Interp *interp, Tcl_Obj *part1Ptr, @@ -3089,16 +2803,14 @@ MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj, Tcl_Obj *patternObj, int flags); MODULE_SCOPE Tcl_Obj * TclStringObjReverse(Tcl_Obj *objPtr); MODULE_SCOPE void TclSubstCompile(Tcl_Interp *interp, const char *bytes, - int numBytes, int flags, int line, - struct CompileEnv *envPtr); + int numBytes, int flags, struct CompileEnv *envPtr); MODULE_SCOPE int TclSubstOptions(Tcl_Interp *interp, int numOpts, Tcl_Obj *const opts[], int *flagPtr); MODULE_SCOPE void TclSubstParse(Tcl_Interp *interp, const char *bytes, int numBytes, int flags, Tcl_Parse *parsePtr, Tcl_InterpState *statePtr); MODULE_SCOPE int TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, - int count, int *tokensLeftPtr, int line, - int *clNextOuter, const char *outerScript); + int count, int *tokensLeftPtr); MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes, const char *trim, int numTrim); MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes, @@ -3134,8 +2846,6 @@ MODULE_SCOPE void TclpThreadDeleteKey(void *keyPtr); MODULE_SCOPE void TclpThreadSetMasterTSD(void *tsdKeyPtr, void *ptr); MODULE_SCOPE void * TclpThreadGetMasterTSD(void *tsdKeyPtr); -MODULE_SCOPE void TclErrorStackResetIf(Tcl_Interp *interp, const char *msg, int length); - /* *---------------------------------------------------------------- * Command procedures in the generic core: diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index c6b8135..0b808a7 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -558,11 +558,8 @@ EXTERN Var * TclObjLookupVar(Tcl_Interp *interp, /* 231 */ EXTERN int TclGetNamespaceFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Namespace **nsPtrPtr); -/* 232 */ -EXTERN int TclEvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, - int flags, const CmdFrame *invoker, int word); -/* 233 */ -EXTERN void TclGetSrcInfoForPc(CmdFrame *contextPtr); +/* Slot 232 is reserved */ +/* Slot 233 is reserved */ /* 234 */ EXTERN Var * TclVarHashCreateVar(TclVarHashTable *tablePtr, const char *key, int *newPtr); @@ -585,7 +582,7 @@ EXTERN int TclNRInterpProcCore(Tcl_Interp *interp, EXTERN int TclNRRunCallbacks(Tcl_Interp *interp, int result); /* 241 */ EXTERN int TclNREvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, - int flags, const CmdFrame *invoker, int word); + int flags); /* 242 */ EXTERN int TclNREvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int flags, @@ -853,8 +850,8 @@ typedef struct TclIntStubs { int (*tclPtrMakeUpvar) (Tcl_Interp *interp, Var *otherP1Ptr, const char *myName, int myFlags, int index); /* 229 */ Var * (*tclObjLookupVar) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, const char *part2, int flags, const char *msg, const int createPart1, const int createPart2, Var **arrayPtrPtr); /* 230 */ int (*tclGetNamespaceFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Namespace **nsPtrPtr); /* 231 */ - int (*tclEvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, const CmdFrame *invoker, int word); /* 232 */ - void (*tclGetSrcInfoForPc) (CmdFrame *contextPtr); /* 233 */ + void (*reserved232)(void); + void (*reserved233)(void); Var * (*tclVarHashCreateVar) (TclVarHashTable *tablePtr, const char *key, int *newPtr); /* 234 */ void (*tclInitVarHashTable) (TclVarHashTable *tablePtr, Namespace *nsPtr); /* 235 */ void (*tclBackgroundException) (Tcl_Interp *interp, int code); /* 236 */ @@ -862,7 +859,7 @@ typedef struct TclIntStubs { int (*tclNRInterpProc) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 238 */ int (*tclNRInterpProcCore) (Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip, ProcErrorProc *errorProc); /* 239 */ int (*tclNRRunCallbacks) (Tcl_Interp *interp, int result); /* 240 */ - int (*tclNREvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, const CmdFrame *invoker, int word); /* 241 */ + int (*tclNREvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 241 */ int (*tclNREvalObjv) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int flags, Command *cmdPtr); /* 242 */ void (*tclDbDumpActiveObjects) (FILE *outFile); /* 243 */ Tcl_HashTable * (*tclGetNamespaceChildTable) (Tcl_Namespace *nsPtr); /* 244 */ @@ -1264,10 +1261,8 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclObjLookupVar) /* 230 */ #define TclGetNamespaceFromObj \ (tclIntStubsPtr->tclGetNamespaceFromObj) /* 231 */ -#define TclEvalObjEx \ - (tclIntStubsPtr->tclEvalObjEx) /* 232 */ -#define TclGetSrcInfoForPc \ - (tclIntStubsPtr->tclGetSrcInfoForPc) /* 233 */ +/* Slot 232 is reserved */ +/* Slot 233 is reserved */ #define TclVarHashCreateVar \ (tclIntStubsPtr->tclVarHashCreateVar) /* 234 */ #define TclInitVarHashTable \ diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 289f13c..d27ed3f 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -2820,17 +2820,7 @@ SlaveEval( Tcl_AllowExceptions(slaveInterp); if (objc == 1) { - /* - * TIP #280: Make actual argument location available to eval'd script. - */ - - Interp *iPtr = (Interp *) interp; - CmdFrame *invoker = iPtr->cmdFramePtr; - int word = 0; - - TclArgumentGet(interp, objv[0], &invoker, &word); - - result = TclEvalObjEx(slaveInterp, objv[0], 0, invoker, word); + result = Tcl_EvalObjEx(slaveInterp, objv[0], 0); } else { Tcl_Obj *objPtr = Tcl_ConcatObj(objc, objv); Tcl_IncrRefCount(objPtr); diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index dfab185..4a59d6e 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -3270,8 +3270,6 @@ NRNamespaceEvalCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; - CmdFrame *invoker; - int word; Tcl_Namespace *namespacePtr; CallFrame *framePtr, **framePtrPtr; Tcl_Obj *objPtr; @@ -3327,9 +3325,6 @@ NRNamespaceEvalCmd( */ objPtr = objv[2]; - invoker = iPtr->cmdFramePtr; - word = 3; - TclArgumentGet(interp, objPtr, &invoker, &word); } else { /* * More than one argument: concatenate them together with spaces @@ -3338,17 +3333,11 @@ NRNamespaceEvalCmd( */ objPtr = Tcl_ConcatObj(objc-2, objv+2); - invoker = NULL; - word = 0; } - /* - * TIP #280: Make invoking context available to eval'd script. - */ - TclNRAddCallback(interp, NsEval_Callback, namespacePtr, "eval", NULL, NULL); - return TclNREvalObjEx(interp, objPtr, 0, invoker, word); + return TclNREvalObjEx(interp, objPtr, 0); } static int @@ -3790,7 +3779,7 @@ NRNamespaceInscopeCmd( TclNRAddCallback(interp, NsEval_Callback, namespacePtr, "inscope", NULL, NULL); - return TclNREvalObjEx(interp, cmdObjPtr, 0, NULL, 0); + return TclNREvalObjEx(interp, cmdObjPtr, 0); } /* @@ -4821,20 +4810,11 @@ TclGetNamespaceChildTable( * * TclLogCommandInfo -- * - * This function is invoked after an error occurs in an interpreter. It - * adds information to iPtr->errorInfo/errorStack fields to describe the - * command that was being executed when the error occurred. When pc and - * tosPtr are non-NULL, conveying a bytecode execution "inner context", - * and the offending instruction is suitable, that inner context is - * recorded in errorStack. + * This function is invoked after an error occurs in an interpreter. * * Results: * None. * - * Side effects: - * Information about the command is added to errorInfo/errorStack and the - * line number stored internally in the interpreter is set. - * *---------------------------------------------------------------------- */ @@ -4916,119 +4896,6 @@ TclLogCommandInfo( } } } - - /* - * TIP #348 - */ - - if (Tcl_IsShared(iPtr->errorStack)) { - Tcl_Obj *newObj; - - newObj = Tcl_DuplicateObj(iPtr->errorStack); - Tcl_DecrRefCount(iPtr->errorStack); - Tcl_IncrRefCount(newObj); - iPtr->errorStack = newObj; - } - if (iPtr->resetErrorStack) { - int len; - - iPtr->resetErrorStack = 0; - Tcl_ListObjLength(interp, iPtr->errorStack, &len); - - /* - * Reset while keeping the list intrep as much as possible. - */ - - Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL); - if (pc != NULL) { - Tcl_Obj *innerContext; - - innerContext = TclGetInnerContext(interp, pc, tosPtr); - if (innerContext != NULL) { - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, - iPtr->innerLiteral); - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, innerContext); - } - } else if (command != NULL) { - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, - iPtr->innerLiteral); - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, - Tcl_NewStringObj(command, length)); - } - } - - if (!iPtr->framePtr->objc) { - /* - * Special frame, nothing to report. - */ - } else if (iPtr->varFramePtr != iPtr->framePtr) { - /* - * uplevel case, [lappend errorstack UP $relativelevel] - */ - - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->upLiteral); - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewIntObj( - iPtr->framePtr->level - iPtr->varFramePtr->level)); - } else if (iPtr->framePtr != iPtr->rootFramePtr) { - /* - * normal case, [lappend errorstack CALL [info level 0]] - */ - - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->callLiteral); - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewListObj( - iPtr->framePtr->objc, iPtr->framePtr->objv)); - } -} - -/* - *---------------------------------------------------------------------- - * - * TclErrorStackResetIf -- - * - * The TIP 348 reset/no-bc part of TLCI, for specific use by - * TclCompileSyntaxError. - * - * Results: - * None. - * - * Side effects: - * Reset errorstack if it needs be, and in that case remember the - * passed-in error message as inner context. - * - *---------------------------------------------------------------------- - */ - -void -TclErrorStackResetIf( - Tcl_Interp *interp, - const char *msg, - int length) -{ - Interp *iPtr = (Interp *) interp; - - if (Tcl_IsShared(iPtr->errorStack)) { - Tcl_Obj *newObj; - - newObj = Tcl_DuplicateObj(iPtr->errorStack); - Tcl_DecrRefCount(iPtr->errorStack); - Tcl_IncrRefCount(newObj); - iPtr->errorStack = newObj; - } - if (iPtr->resetErrorStack) { - int len; - - iPtr->resetErrorStack = 0; - Tcl_ListObjLength(interp, iPtr->errorStack, &len); - - /* - * Reset while keeping the list intrep as much as possible. - */ - - Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL); - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->innerLiteral); - Tcl_ListObjAppendElement(NULL, iPtr->errorStack, - Tcl_NewStringObj(msg, length)); - } } /* @@ -5036,17 +4903,11 @@ TclErrorStackResetIf( * * Tcl_LogCommandInfo -- * - * This function is invoked after an error occurs in an interpreter. It - * adds information to iPtr->errorInfo/errorStack fields to describe the - * command that was being executed when the error occurred. + * This function is invoked after an error occurs in an interpreter. * * Results: * None. * - * Side effects: - * Information about the command is added to errorInfo/errorStack and the - * line number stored internally in the interpreter is set. - * *---------------------------------------------------------------------- */ diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index c093059..6cf505a 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -403,7 +403,6 @@ TclOO_Object_Eval( register const int skip = Tcl_ObjectContextSkippedArgs(context); CallFrame *framePtr, **framePtrPtr = &framePtr; Tcl_Obj *scriptPtr; - CmdFrame *invoker; if (objc-1 < skip) { Tcl_WrongNumArgs(interp, skip, objv, "arg ?arg ...?"); @@ -435,10 +434,8 @@ TclOO_Object_Eval( if (objc != skip+1) { scriptPtr = Tcl_ConcatObj(objc-skip, objv+skip); - invoker = NULL; } else { scriptPtr = objv[skip]; - invoker = ((Interp *) interp)->cmdFramePtr; } /* @@ -447,7 +444,7 @@ TclOO_Object_Eval( */ TclNRAddCallback(interp, FinalizeEval, object, NULL, NULL, NULL); - return TclNREvalObjEx(interp, scriptPtr, 0, invoker, skip); + return TclNREvalObjEx(interp, scriptPtr, 0); } static int diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index c880754..cecc55e 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -839,8 +839,7 @@ TclOODefineObjCmd( Tcl_Obj *objNameObj = TclOOObjectName(interp, oPtr); Tcl_IncrRefCount(objNameObj); - result = TclEvalObjEx(interp, objv[2], 0, - ((Interp *)interp)->cmdFramePtr, 2); + result = Tcl_EvalObjEx(interp, objv[2], 0); if (result == TCL_ERROR) { GenerateErrorInfo(interp, oPtr, objNameObj, "class"); } @@ -954,8 +953,7 @@ TclOOObjDefObjCmd( Tcl_Obj *objNameObj = TclOOObjectName(interp, oPtr); Tcl_IncrRefCount(objNameObj); - result = TclEvalObjEx(interp, objv[2], 0, - ((Interp *)interp)->cmdFramePtr, 2); + result = Tcl_EvalObjEx(interp, objv[2], 0); if (result == TCL_ERROR) { GenerateErrorInfo(interp, oPtr, objNameObj, "object"); } @@ -1069,8 +1067,7 @@ TclOODefineSelfObjCmd( Tcl_Obj *objNameObj = TclOOObjectName(interp, oPtr); Tcl_IncrRefCount(objNameObj); - result = TclEvalObjEx(interp, objv[1], 0, - ((Interp *)interp)->cmdFramePtr, 2); + result = Tcl_EvalObjEx(interp, objv[1], 0); if (result == TCL_ERROR) { GenerateErrorInfo(interp, oPtr, objNameObj, "class object"); } diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index b75ffdb..b5cd508 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -94,9 +94,6 @@ typedef struct ProcedureMethod { TclOO_PostCallProc *postCallProc; /* Callback to allow for additional cleanup * after the method executes. */ - GetFrameInfoValueProc *gfivProc; - /* Callback to allow for fine tuning of how - * the method reports itself. */ } ProcedureMethod; #define TCLOO_PROCEDURE_METHOD_VERSION 0 diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c index 34fa108..83be0aa 100644 --- a/generic/tclOOMethod.c +++ b/generic/tclOOMethod.c @@ -38,7 +38,6 @@ typedef struct { ProcErrorProc *errProc; /* The error handler for the body. */ Tcl_Obj *nameObj; /* The "name" of the command. */ Command cmd; /* The command structure. Mostly bogus. */ - ExtraFrameInfo efi; /* Extra information used for [info frame]. */ Command *oldCmdPtr; /* Saved cmdPtr so that we can be safe after a * recursive call returns. */ struct PNI pni; /* Specialist information used in the efi @@ -88,7 +87,6 @@ static void ConstructorErrorHandler(Tcl_Interp *interp, Tcl_Obj *procNameObj); static void DestructorErrorHandler(Tcl_Interp *interp, Tcl_Obj *procNameObj); -static Tcl_Obj * RenderDeclarerName(ClientData clientData); static int InvokeForwardMethod(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); @@ -458,7 +456,6 @@ TclOOMakeProcInstanceMethod( * inside the structure indicated by the * pointer in clientData. */ { - Interp *iPtr = (Interp *) interp; Proc *procPtr; if (TclCreateProc(interp, NULL, TclGetString(nameObj), argsObj, bodyObj, @@ -468,69 +465,6 @@ TclOOMakeProcInstanceMethod( procPtr = *procPtrPtr; procPtr->cmdPtr = NULL; - if (iPtr->cmdFramePtr) { - CmdFrame context = *iPtr->cmdFramePtr; - - if (context.type == TCL_LOCATION_BC) { - /* - * Retrieve source information from the bytecode, if possible. If - * the information is retrieved successfully, context.type will be - * TCL_LOCATION_SOURCE and the reference held by - * context.data.eval.path will be counted. - */ - - TclGetSrcInfoForPc(&context); - } else if (context.type == TCL_LOCATION_SOURCE) { - /* - * The copy into 'context' up above has created another reference - * to 'context.data.eval.path'; account for it. - */ - - Tcl_IncrRefCount(context.data.eval.path); - } - - if (context.type == TCL_LOCATION_SOURCE) { - /* - * We can account for source location within a proc only if the - * proc body was not created by substitution. - * (FIXME: check that this is sane and correct!) - */ - - if (context.line - && (context.nline >= 4) && (context.line[3] >= 0)) { - int isNew; - CmdFrame *cfPtr = ckalloc(sizeof(CmdFrame)); - Tcl_HashEntry *hPtr; - - cfPtr->level = -1; - cfPtr->type = context.type; - cfPtr->line = ckalloc(sizeof(int)); - cfPtr->line[0] = context.line[3]; - cfPtr->nline = 1; - cfPtr->framePtr = NULL; - cfPtr->nextPtr = NULL; - - cfPtr->data.eval.path = context.data.eval.path; - Tcl_IncrRefCount(cfPtr->data.eval.path); - - cfPtr->cmd = NULL; - cfPtr->len = 0; - - hPtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr, - (char *) procPtr, &isNew); - Tcl_SetHashValue(hPtr, cfPtr); - } - - /* - * 'context' is going out of scope; account for the reference that - * it's holding to the path name. - */ - - Tcl_DecrRefCount(context.data.eval.path); - context.data.eval.path = NULL; - } - } - return Tcl_NewInstanceMethod(interp, (Tcl_Object) oPtr, nameObj, flags, typePtr, clientData); } @@ -571,7 +505,6 @@ TclOOMakeProcMethod( * inside the structure indicated by the * pointer in clientData. */ { - Interp *iPtr = (Interp *) interp; Proc *procPtr; if (TclCreateProc(interp, NULL, namePtr, argsObj, bodyObj, @@ -581,69 +514,6 @@ TclOOMakeProcMethod( procPtr = *procPtrPtr; procPtr->cmdPtr = NULL; - if (iPtr->cmdFramePtr) { - CmdFrame context = *iPtr->cmdFramePtr; - - if (context.type == TCL_LOCATION_BC) { - /* - * Retrieve source information from the bytecode, if possible. If - * the information is retrieved successfully, context.type will be - * TCL_LOCATION_SOURCE and the reference held by - * context.data.eval.path will be counted. - */ - - TclGetSrcInfoForPc(&context); - } else if (context.type == TCL_LOCATION_SOURCE) { - /* - * The copy into 'context' up above has created another reference - * to 'context.data.eval.path'; account for it. - */ - - Tcl_IncrRefCount(context.data.eval.path); - } - - if (context.type == TCL_LOCATION_SOURCE) { - /* - * We can account for source location within a proc only if the - * proc body was not created by substitution. - * (FIXME: check that this is sane and correct!) - */ - - if (context.line - && (context.nline >= 4) && (context.line[3] >= 0)) { - int isNew; - CmdFrame *cfPtr = ckalloc(sizeof(CmdFrame)); - Tcl_HashEntry *hPtr; - - cfPtr->level = -1; - cfPtr->type = context.type; - cfPtr->line = ckalloc(sizeof(int)); - cfPtr->line[0] = context.line[3]; - cfPtr->nline = 1; - cfPtr->framePtr = NULL; - cfPtr->nextPtr = NULL; - - cfPtr->data.eval.path = context.data.eval.path; - Tcl_IncrRefCount(cfPtr->data.eval.path); - - cfPtr->cmd = NULL; - cfPtr->len = 0; - - hPtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr, - (char *) procPtr, &isNew); - Tcl_SetHashValue(hPtr, cfPtr); - } - - /* - * 'context' is going out of scope; account for the reference that - * it's holding to the path name. - */ - - Tcl_DecrRefCount(context.data.eval.path); - context.data.eval.path = NULL; - } - } - return Tcl_NewMethod(interp, (Tcl_Class) clsPtr, nameObj, flags, typePtr, clientData); } @@ -845,10 +715,8 @@ PushMethodCallFrame( * Compile the body. This operation may fail. */ - fdPtr->efi.length = 2; memset(&fdPtr->cmd, 0, sizeof(Command)); fdPtr->cmd.nsPtr = nsPtr; - fdPtr->cmd.clientData = &fdPtr->efi; pmPtr->procPtr->cmdPtr = &fdPtr->cmd; /* @@ -883,32 +751,6 @@ PushMethodCallFrame( fdPtr->framePtr->objv = objv; fdPtr->framePtr->procPtr = pmPtr->procPtr; - /* - * Finish filling out the extra frame info so that [info frame] works. - */ - - fdPtr->efi.fields[0].name = "method"; - fdPtr->efi.fields[0].proc = NULL; - fdPtr->efi.fields[0].clientData = fdPtr->nameObj; - if (pmPtr->gfivProc != NULL) { - fdPtr->efi.fields[1].name = ""; - fdPtr->efi.fields[1].proc = pmPtr->gfivProc; - fdPtr->efi.fields[1].clientData = pmPtr; - } else { - register Tcl_Method method = - Tcl_ObjectContextMethod((Tcl_ObjectContext) contextPtr); - - if (Tcl_MethodDeclarerObject(method) != NULL) { - fdPtr->efi.fields[1].name = "object"; - } else { - fdPtr->efi.fields[1].name = "class"; - } - fdPtr->efi.fields[1].proc = RenderDeclarerName; - fdPtr->efi.fields[1].clientData = &fdPtr->pni; - fdPtr->pni.interp = interp; - fdPtr->pni.method = method; - } - return TCL_OK; /* @@ -1117,32 +959,6 @@ ProcedureMethodCompiledVarResolver( /* * ---------------------------------------------------------------------- * - * RenderDeclarerName -- - * - * Returns the name of the entity (object or class) which declared a - * method. Used for producing information for [info frame] in such a way - * that the expensive part of this (generating the object or class name - * itself) isn't done until it is needed. - * - * ---------------------------------------------------------------------- - */ - -static Tcl_Obj * -RenderDeclarerName( - ClientData clientData) -{ - struct PNI *pni = clientData; - Tcl_Object object = Tcl_MethodDeclarerObject(pni->method); - - if (object == NULL) { - object = Tcl_GetClassAsObject(Tcl_MethodDeclarerClass(pni->method)); - } - return TclOOObjectName(pni->interp, (Object *) object); -} - -/* - * ---------------------------------------------------------------------- - * * MethodErrorHandler, ConstructorErrorHandler, DestructorErrorHandler -- * * How to fill in the stack trace correctly upon error in various forms diff --git a/generic/tclObj.c b/generic/tclObj.c index c641152..9058264 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -51,21 +51,6 @@ Tcl_Mutex tclObjMutex; char tclEmptyString = '\0'; char *tclEmptyStringRep = &tclEmptyString; -#if defined(TCL_MEM_DEBUG) && defined(TCL_THREADS) -/* - * Structure for tracking the source file and line number where a given - * Tcl_Obj was allocated. We also track the pointer to the Tcl_Obj itself, - * for sanity checking purposes. - */ - -typedef struct ObjData { - Tcl_Obj *objPtr; /* The pointer to the allocated Tcl_Obj. */ - const char *file; /* The name of the source file calling this - * function; used for debugging. */ - int line; /* Line number in the source file; used for - * debugging. */ -} ObjData; -#endif /* TCL_MEM_DEBUG && TCL_THREADS */ /* * All static variables used in this file are collected into a single instance @@ -77,17 +62,6 @@ typedef struct ObjData { */ typedef struct ThreadSpecificData { - Tcl_HashTable *lineCLPtr; /* This table remembers for each Tcl_Obj - * generated by a call to the function - * TclSubstTokens() from a literal text - * where bs+nl sequences occured in it, if - * any. I.e. this table keeps track of - * invisible and stripped continuation lines. - * Its keys are Tcl_Obj pointers, the values - * are ContLineLoc pointers. See the file - * tclCompile.h for the definition of this - * structure, and for references to all - * related places in the core. */ #if defined(TCL_MEM_DEBUG) && defined(TCL_THREADS) Tcl_HashTable *objThreadMap;/* Thread local table that is used to check * that a Tcl_Obj was not allocated by some @@ -95,11 +69,6 @@ typedef struct ThreadSpecificData { #endif /* TCL_MEM_DEBUG && TCL_THREADS */ } ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; - -static void TclThreadFinalizeContLines(ClientData clientData); -static ThreadSpecificData *TclGetContLineTable(void); - /* * Nested Tcl_Obj deletion management support * @@ -509,310 +478,6 @@ TclFinalizeObjects(void) } /* - *---------------------------------------------------------------------- - * - * TclGetContLineTable -- - * - * This procedure is a helper which returns the thread-specific - * hash-table used to track continuation line information associated with - * Tcl_Obj*, and the objThreadMap, etc. - * - * Results: - * A reference to the thread-data. - * - * Side effects: - * May allocate memory for the thread-data. - * - * TIP #280 - *---------------------------------------------------------------------- - */ - -static ThreadSpecificData * -TclGetContLineTable(void) -{ - /* - * Initialize the hashtable tracking invisible continuation lines. For - * the release we use a thread exit handler to ensure that this is done - * before TSD blocks are made invalid. The TclFinalizeObjects() which - * would be the natural place for this is invoked afterwards, meaning that - * we try to operate on a data structure already gone. - */ - - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - if (!tsdPtr->lineCLPtr) { - tsdPtr->lineCLPtr = ckalloc(sizeof(Tcl_HashTable)); - Tcl_InitHashTable(tsdPtr->lineCLPtr, TCL_ONE_WORD_KEYS); - Tcl_CreateThreadExitHandler(TclThreadFinalizeContLines,NULL); - } - return tsdPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TclContinuationsEnter -- - * - * This procedure is a helper which saves the continuation line - * information associated with a Tcl_Obj*. - * - * Results: - * A reference to the newly created continuation line location table. - * - * Side effects: - * Allocates memory for the table of continuation line locations. - * - * TIP #280 - *---------------------------------------------------------------------- - */ - -ContLineLoc * -TclContinuationsEnter( - Tcl_Obj *objPtr, - int num, - int *loc) -{ - int newEntry; - ThreadSpecificData *tsdPtr = TclGetContLineTable(); - Tcl_HashEntry *hPtr = - Tcl_CreateHashEntry(tsdPtr->lineCLPtr, objPtr, &newEntry); - ContLineLoc *clLocPtr = ckalloc(sizeof(ContLineLoc) + num*sizeof(int)); - - if (!newEntry) { - /* - * We're entering ContLineLoc data for the same value more than one - * time. Taking care not to leak the old entry. - * - * This can happen when literals in a proc body are shared. See for - * example test info-30.19 where the action (code) for all branches of - * the switch command is identical, mapping them all to the same - * literal. An interesting result of this is that the number and - * locations (offset) of invisible continuation lines in the literal - * are the same for all occurences. - * - * Note that while reusing the existing entry is possible it requires - * the same actions as for a new entry because we have to copy the - * incoming num/loc data even so. Because we are called from - * TclContinuationsEnterDerived for this case, which modified the - * stored locations (Rebased to the proper relative offset). Just - * returning the stored entry would rebase them a second time, or - * more, hosing the data. It is easier to simply replace, as we are - * doing. - */ - - ckfree(Tcl_GetHashValue(hPtr)); - } - - clLocPtr->num = num; - memcpy(&clLocPtr->loc, loc, num*sizeof(int)); - clLocPtr->loc[num] = CLL_END; /* Sentinel */ - Tcl_SetHashValue(hPtr, clLocPtr); - - return clLocPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TclContinuationsEnterDerived -- - * - * This procedure is a helper which computes the continuation line - * information associated with a Tcl_Obj* cut from the middle of a - * script. - * - * Results: - * None. - * - * Side effects: - * Allocates memory for the table of continuation line locations. - * - * TIP #280 - *---------------------------------------------------------------------- - */ - -void -TclContinuationsEnterDerived( - Tcl_Obj *objPtr, - int start, - int *clNext) -{ - int length, end, num; - int *wordCLLast = clNext; - - /* - * We have to handle invisible continuations lines here as well, despite - * the code we have in TclSubstTokens (TST) for that. Why ? Nesting. If - * our script is the sole argument to an 'eval' command, for example, the - * scriptCLLocPtr we are using was generated by a previous call to TST, - * and while the words we have here may contain continuation lines they - * are invisible already, and the inner call to TST had no bs+nl sequences - * to trigger its code. - * - * Luckily for us, the table we have to create here for the current word - * has to be a slice of the table currently in use, with the locations - * suitably modified to be relative to the start of the word instead of - * relative to the script. - * - * That is what we are doing now. Determine the slice we need, and if not - * empty, wrap it into a new table, and save the result into our - * thread-global hashtable, as usual. - */ - - /* - * First compute the range of the word within the script. (Is there a - * better way which doesn't shimmer?) - */ - - Tcl_GetStringFromObj(objPtr, &length); - end = start + length; /* First char after the word */ - - /* - * Then compute the table slice covering the range of the word. - */ - - while (*wordCLLast >= 0 && *wordCLLast < end) { - wordCLLast++; - } - - /* - * And generate the table from the slice, if it was not empty. - */ - - num = wordCLLast - clNext; - if (num) { - int i; - ContLineLoc *clLocPtr = TclContinuationsEnter(objPtr, num, clNext); - - /* - * Re-base the locations. - */ - - for (i=0 ; i<num ; i++) { - clLocPtr->loc[i] -= start; - - /* - * Continuation lines coming before the string and affecting us - * should not happen, due to the proper maintenance of clNext - * during compilation. - */ - - if (clLocPtr->loc[i] < 0) { - Tcl_Panic("Derived ICL data for object using offsets from before the script"); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TclContinuationsCopy -- - * - * This procedure is a helper which copies the continuation line - * information associated with a Tcl_Obj* to another Tcl_Obj*. It is - * assumed that both contain the same string/script. Use this when a - * script is duplicated because it was shared. - * - * Results: - * None. - * - * Side effects: - * Allocates memory for the table of continuation line locations. - * - * TIP #280 - *---------------------------------------------------------------------- - */ - -void -TclContinuationsCopy( - Tcl_Obj *objPtr, - Tcl_Obj *originObjPtr) -{ - ThreadSpecificData *tsdPtr = TclGetContLineTable(); - Tcl_HashEntry *hPtr = - Tcl_FindHashEntry(tsdPtr->lineCLPtr, originObjPtr); - - if (hPtr) { - ContLineLoc *clLocPtr = Tcl_GetHashValue(hPtr); - - TclContinuationsEnter(objPtr, clLocPtr->num, clLocPtr->loc); - } -} - -/* - *---------------------------------------------------------------------- - * - * TclContinuationsGet -- - * - * This procedure is a helper which retrieves the continuation line - * information associated with a Tcl_Obj*, if it has any. - * - * Results: - * A reference to the continuation line location table, or NULL if the - * Tcl_Obj* has no such information associated with it. - * - * Side effects: - * None. - * - * TIP #280 - *---------------------------------------------------------------------- - */ - -ContLineLoc * -TclContinuationsGet( - Tcl_Obj *objPtr) -{ - ThreadSpecificData *tsdPtr = TclGetContLineTable(); - Tcl_HashEntry *hPtr = - Tcl_FindHashEntry(tsdPtr->lineCLPtr, objPtr); - - if (!hPtr) { - return NULL; - } - return Tcl_GetHashValue(hPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TclThreadFinalizeContLines -- - * - * This procedure is a helper which releases all continuation line - * information currently known. It is run as a thread exit handler. - * - * Results: - * None. - * - * Side effects: - * Releases memory. - * - * TIP #280 - *---------------------------------------------------------------------- - */ - -static void -TclThreadFinalizeContLines( - ClientData clientData) -{ - /* - * Release the hashtable tracking invisible continuation lines. - */ - - ThreadSpecificData *tsdPtr = TclGetContLineTable(); - Tcl_HashEntry *hPtr; - Tcl_HashSearch hSearch; - - for (hPtr = Tcl_FirstHashEntry(tsdPtr->lineCLPtr, &hSearch); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { - ckfree(Tcl_GetHashValue(hPtr)); - Tcl_DeleteHashEntry(hPtr); - } - Tcl_DeleteHashTable(tsdPtr->lineCLPtr); - ckfree(tsdPtr->lineCLPtr); - tsdPtr->lineCLPtr = NULL; -} - -/* *-------------------------------------------------------------- * * Tcl_RegisterObjType -- @@ -1388,29 +1053,6 @@ TclFreeObj( } ObjDeletionUnlock(context); } - - /* - * We cannot use TclGetContinuationTable() here, because that may - * re-initialize the thread-data for calls coming after the finalization. - * We have to access it using the low-level call and then check for - * validity. This function can be called after TclFinalizeThreadData() has - * already killed the thread-global data structures. Performing - * TCL_TSD_INIT will leave us with an un-initialized memory block upon - * which we crash (if we where to access the uninitialized hashtable). - */ - - { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - Tcl_HashEntry *hPtr; - - if (tsdPtr->lineCLPtr) { - hPtr = Tcl_FindHashEntry(tsdPtr->lineCLPtr, objPtr); - if (hPtr) { - ckfree(Tcl_GetHashValue(hPtr)); - Tcl_DeleteHashEntry(hPtr); - } - } - } } #else /* TCL_MEM_DEBUG */ @@ -1479,29 +1121,6 @@ TclFreeObj( ObjDeletionUnlock(context); } } - - /* - * We cannot use TclGetContinuationTable() here, because that may - * re-initialize the thread-data for calls coming after the finalization. - * We have to access it using the low-level call and then check for - * validity. This function can be called after TclFinalizeThreadData() has - * already killed the thread-global data structures. Performing - * TCL_TSD_INIT will leave us with an un-initialized memory block upon - * which we crash (if we where to access the uninitialized hashtable). - */ - - { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - Tcl_HashEntry *hPtr; - - if (tsdPtr->lineCLPtr) { - hPtr = Tcl_FindHashEntry(tsdPtr->lineCLPtr, objPtr); - if (hPtr) { - ckfree(Tcl_GetHashValue(hPtr)); - Tcl_DeleteHashEntry(hPtr); - } - } - } } #endif /* TCL_MEM_DEBUG */ diff --git a/generic/tclOptimize.c b/generic/tclOptimize.c index 7249eb6..e71532e 100644 --- a/generic/tclOptimize.c +++ b/generic/tclOptimize.c @@ -170,7 +170,7 @@ Initialize( INIT_PATHS; INIT_SIZE; int i, last; - /* + /* * Initialize PATHS to 0. */ @@ -197,7 +197,11 @@ Initialize( CmdLocation *cmdMapPtr = &envPtr->cmdMapPtr[i]; if (cmdMapPtr->codeOffset == last) continue; last = cmdMapPtr->codeOffset; - MARK(last + cmdMapPtr->numCodeBytes); + if (last + cmdMapPtr->numCodeBytes < codeSize) { + MARK(last + cmdMapPtr->numCodeBytes); + } else { + MARK(codeSize - 1); + } } /* @@ -651,6 +655,10 @@ markPath( PUSH(pc); while (POP(pc) != -1) { + if ((pc < 0) || (pc > padPtr->codeSize)) { + Tcl_Panic("ERR in markPath: pc out of range"); + } + inst = INST_AT_PC(pc); nextpc = NEXT_PC(pc); mark = (PATHS[pc] > 0); diff --git a/generic/tclParse.c b/generic/tclParse.c index 95abc45..95e0571 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -1596,7 +1596,7 @@ Tcl_ParseVar( } code = TclSubstTokens(interp, parsePtr->tokenPtr, parsePtr->numTokens, - NULL, 1, NULL, NULL); + NULL); Tcl_FreeParse(parsePtr); TclStackFree(interp, parsePtr); if (code != TCL_OK) { @@ -2138,33 +2138,13 @@ TclSubstTokens( * evaluate and concatenate. */ int count, /* Number of tokens to consider at tokenPtr. * Must be at least 1. */ - int *tokensLeftPtr, /* If not NULL, points to memory where an + int *tokensLeftPtr) /* If not NULL, points to memory where an * integer representing the number of tokens * left to be substituted will be written */ - 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 by - * EvalEx() 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 words in the outer-most script or - * command. See Tcl_EvalEx and TclEvalObjEx - * for the places generating arguments for - * which this is true. */ { Tcl_Obj *result; int code = TCL_OK; #define NUM_STATIC_POS 20 - int isLiteral, maxNumCL, numCL, i, adjust; - int *clPosition = NULL; Interp *iPtr = (Interp *) interp; int inFile = iPtr->evalFlags & TCL_EVAL_FILE; @@ -2178,31 +2158,6 @@ TclSubstTokens( * of Tcl_SetObjResult(interp, Tcl_GetObjResult(interp)) and omit them. */ - /* - * For the handling of continuation lines in literals we first check if - * this is actually a literal. For if not we can forego the additional - * processing. Otherwise we pre-allocate a small table to store the - * locations of all continuation lines we find in this literal, if any. - * The table is extended if needed. - */ - - numCL = 0; - maxNumCL = 0; - isLiteral = 1; - for (i=0 ; i < count; i++) { - if ((tokenPtr[i].type != TCL_TOKEN_TEXT) - && (tokenPtr[i].type != TCL_TOKEN_BS)) { - isLiteral = 0; - break; - } - } - - if (isLiteral) { - maxNumCL = NUM_STATIC_POS; - clPosition = ckalloc(maxNumCL * sizeof(int)); - } - - adjust = 0; result = NULL; for (; count>0 && code==TCL_OK ; count--, tokenPtr++) { Tcl_Obj *appendObj = NULL; @@ -2220,64 +2175,13 @@ TclSubstTokens( appendByteLength = TclParseBackslash(tokenPtr->start, tokenPtr->size, NULL, utfCharBytes); append = utfCharBytes; - - /* - * If the backslash sequence we found is in a literal, and - * represented a continuation line, we compute and store its - * location (as char offset to the beginning of the _result_ - * script). We may have to extend the table of locations. - * - * Note that the continuation line information is relevant even if - * the word we are processing is not a literal, as it can affect - * nested commands. See the branch for TCL_TOKEN_COMMAND below, - * where the adjustment we are tracking here is taken into - * account. The good thing is that we do not need a table of - * everything, just the number of lines we have to add as - * correction. - */ - - if ((appendByteLength == 1) && (utfCharBytes[0] == ' ') - && (tokenPtr->start[1] == '\n')) { - if (isLiteral) { - int clPos; - - if (result == 0) { - clPos = 0; - } else { - Tcl_GetStringFromObj(result, &clPos); - } - - if (numCL >= maxNumCL) { - maxNumCL *= 2; - clPosition = ckrealloc(clPosition, - maxNumCL * sizeof(int)); - } - clPosition[numCL] = clPos; - numCL++; - } - adjust++; - } break; case TCL_TOKEN_COMMAND: { - /* TIP #280: Transfer line information to nested command */ iPtr->numLevels++; code = TclInterpReady(interp); if (code == TCL_OK) { - /* - * Test cases: info-30.{6,8,9} - */ - - int theline; - - TclAdvanceContinuations(&line, &clNextOuter, - tokenPtr->start - outerScript); - theline = line + adjust; - code = TclEvalEx(interp, tokenPtr->start+1, tokenPtr->size-2, - 0, theline, clNextOuter, outerScript); - - TclAdvanceLines(&line, tokenPtr->start+1, - tokenPtr->start + tokenPtr->size - 1); + code = Tcl_EvalEx(interp, tokenPtr->start+1, tokenPtr->size-2, 0); /* * Restore flag reset by nested eval for future bracketed @@ -2304,7 +2208,7 @@ TclSubstTokens( */ code = TclSubstTokens(interp, tokenPtr+2, - tokenPtr->numComponents - 1, NULL, line, NULL, NULL); + tokenPtr->numComponents - 1, NULL); arrayIndex = Tcl_GetObjResult(interp); Tcl_IncrRefCount(arrayIndex); } @@ -2388,27 +2292,6 @@ TclSubstTokens( if (code != TCL_ERROR) { /* Keep error message in result! */ if (result != NULL) { Tcl_SetObjResult(interp, result); - - /* - * If the code found continuation lines (which implies that this - * word is a literal), then we store the accumulated table of - * locations in the thread-global data structure for the bytecode - * compiler to find later, assuming that the literal is a script - * which will be compiled. - */ - - if (numCL) { - TclContinuationsEnter(result, numCL, clPosition); - } - - /* - * Release the temp table we used to collect the locations of - * continuation lines, if any. - */ - - if (maxNumCL) { - ckfree(clPosition); - } } else { Tcl_ResetResult(interp); } diff --git a/generic/tclProc.c b/generic/tclProc.c index ac65bde..ffde29d 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -24,7 +24,6 @@ typedef struct { int isRootEnsemble; Command cmd; - ExtraFrameInfo efi; } ApplyExtraData; /* @@ -210,101 +209,6 @@ Tcl_ProcObjCmd( procPtr->cmdPtr = (Command *) cmd; /* - * TIP #280: Remember the line the procedure body is starting on. In a - * bytecode context we ask the engine to provide us with the necessary - * information. This is for the initialization of the byte code compiler - * when the body is used for the first time. - * - * This code is nearly identical to the #280 code in SetLambdaFromAny, see - * this file. The differences are the different index of the body in the - * line array of the context, and the lambda code requires some special - * processing. Find a way to factor the common elements into a single - * function. - */ - - if (iPtr->cmdFramePtr) { - CmdFrame *contextPtr = TclStackAlloc(interp, sizeof(CmdFrame)); - - *contextPtr = *iPtr->cmdFramePtr; - if (contextPtr->type == TCL_LOCATION_BC) { - /* - * Retrieve source information from the bytecode, if possible. If - * the information is retrieved successfully, context.type will be - * TCL_LOCATION_SOURCE and the reference held by - * context.data.eval.path will be counted. - */ - - TclGetSrcInfoForPc(contextPtr); - } else if (contextPtr->type == TCL_LOCATION_SOURCE) { - /* - * The copy into 'context' up above has created another reference - * to 'context.data.eval.path'; account for it. - */ - - Tcl_IncrRefCount(contextPtr->data.eval.path); - } - - if (contextPtr->type == TCL_LOCATION_SOURCE) { - /* - * We can account for source location within a proc only if the - * proc body was not created by substitution. - */ - - if (contextPtr->line - && (contextPtr->nline >= 4) && (contextPtr->line[3] >= 0)) { - int isNew; - Tcl_HashEntry *hePtr; - CmdFrame *cfPtr = ckalloc(sizeof(CmdFrame)); - - cfPtr->level = -1; - cfPtr->type = contextPtr->type; - cfPtr->line = ckalloc(sizeof(int)); - cfPtr->line[0] = contextPtr->line[3]; - cfPtr->nline = 1; - cfPtr->framePtr = NULL; - cfPtr->nextPtr = NULL; - - cfPtr->data.eval.path = contextPtr->data.eval.path; - Tcl_IncrRefCount(cfPtr->data.eval.path); - - cfPtr->cmd = NULL; - cfPtr->len = 0; - - hePtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr, - procPtr, &isNew); - if (!isNew) { - /* - * Get the old command frame and release it. See also - * TclProcCleanupProc in this file. Currently it seems as - * if only the procbodytest::proc command of the testsuite - * is able to trigger this situation. - */ - - CmdFrame *cfOldPtr = Tcl_GetHashValue(hePtr); - - if (cfOldPtr->type == TCL_LOCATION_SOURCE) { - Tcl_DecrRefCount(cfOldPtr->data.eval.path); - cfOldPtr->data.eval.path = NULL; - } - ckfree(cfOldPtr->line); - cfOldPtr->line = NULL; - ckfree(cfOldPtr); - } - Tcl_SetHashValue(hePtr, cfPtr); - } - - /* - * 'contextPtr' is going out of scope; account for the reference - * that it's holding to the path name. - */ - - Tcl_DecrRefCount(contextPtr->data.eval.path); - contextPtr->data.eval.path = NULL; - } - TclStackFree(interp, contextPtr); - } - - /* * Optimize for no-op procs: if the body is not precompiled (like a TclPro * procbody), and the argument list is just "args" and the body is empty, * define a compileProc to compile a no-op. @@ -438,18 +342,8 @@ TclCreateProc( */ if (Tcl_IsShared(bodyPtr)) { - Tcl_Obj *sharedBodyPtr = bodyPtr; - bytes = TclGetStringFromObj(bodyPtr, &length); bodyPtr = Tcl_NewStringObj(bytes, length); - - /* - * TIP #280. - * Ensure that the continuation line data for the original body is - * not lost and applies to the new body as well. - */ - - TclContinuationsCopy(bodyPtr, sharedBodyPtr); } /* @@ -959,8 +853,6 @@ TclNRUplevelObjCmd( { register Interp *iPtr = (Interp *) interp; - CmdFrame *invoker = NULL; - int word = 0; int result; CallFrame *savedVarFramePtr, *framePtr; Tcl_Obj *objPtr; @@ -997,11 +889,6 @@ TclNRUplevelObjCmd( */ if (objc == 1) { - /* - * TIP #280. Make actual argument location available to eval'd script - */ - - TclArgumentGet(interp, objv[0], &invoker, &word); objPtr = objv[0]; } else { @@ -1016,7 +903,7 @@ TclNRUplevelObjCmd( TclNRAddCallback(interp, Uplevel_Callback, savedVarFramePtr, NULL, NULL, NULL); - return TclNREvalObjEx(interp, objPtr, 0, invoker, word); + return TclNREvalObjEx(interp, objPtr, 0); } /* @@ -1783,14 +1670,6 @@ TclNRInterpProcCore( TCL_DTRACE_PROC_ARGS(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]); } - if (TCL_DTRACE_PROC_INFO_ENABLED() && iPtr->cmdFramePtr) { - Tcl_Obj *info = TclInfoFrame(interp, iPtr->cmdFramePtr); - const char *a[6]; int i[2]; - - TclDTraceInfo(info, a, i); - TCL_DTRACE_PROC_INFO(a[0], a[1], a[2], a[3], i[0], i[1], a[4], a[5]); - TclDecrRefCount(info); - } if (TCL_DTRACE_PROC_ENTRY_ENABLED()) { int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0; @@ -1988,8 +1867,6 @@ TclProcCompileProc( } if (bodyPtr->typePtr != &tclByteCodeType) { - Tcl_HashEntry *hePtr; - #ifdef TCL_COMPILE_DEBUG if (tclTraceCompile >= 1) { /* @@ -2055,21 +1932,7 @@ TclProcCompileProc( (void) TclPushStackFrame(interp, &framePtr, (Tcl_Namespace *) nsPtr, /* isProcCallFrame */ 0); - /* - * TIP #280: We get the invoking context from the cmdFrame which - * was saved by 'Tcl_ProcObjCmd' (using linePBodyPtr). - */ - - hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, (char *) procPtr); - - /* - * Constructed saved frame has body as word 0. See Tcl_ProcObjCmd. - */ - - iPtr->invokeWord = 0; - iPtr->invokeCmdFramePtr = (hePtr ? Tcl_GetHashValue(hePtr) : NULL); TclSetByteCodeFromAny(interp, bodyPtr, NULL, NULL); - iPtr->invokeCmdFramePtr = NULL; TclPopStackFrame(interp); } else if (codePtr->nsEpoch != nsPtr->resolverEpoch) { /* @@ -2174,9 +2037,6 @@ TclProcCleanupProc( Tcl_Obj *bodyPtr = procPtr->bodyPtr; Tcl_Obj *defPtr; Tcl_ResolvedVarInfo *resVarInfo; - Tcl_HashEntry *hePtr = NULL; - CmdFrame *cfPtr = NULL; - Interp *iPtr = procPtr->iPtr; if (bodyPtr != NULL) { Tcl_DecrRefCount(bodyPtr); @@ -2201,34 +2061,6 @@ TclProcCleanupProc( localPtr = nextPtr; } ckfree(procPtr); - - /* - * TIP #280: Release the location data associated with this Proc - * structure, if any. The interpreter may not exist (For example for - * procbody structures created by tbcload. - */ - - if (iPtr == NULL) { - return; - } - - hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, (char *) procPtr); - if (!hePtr) { - return; - } - - cfPtr = Tcl_GetHashValue(hePtr); - - if (cfPtr) { - if (cfPtr->type == TCL_LOCATION_SOURCE) { - Tcl_DecrRefCount(cfPtr->data.eval.path); - cfPtr->data.eval.path = NULL; - } - ckfree(cfPtr->line); - cfPtr->line = NULL; - ckfree(cfPtr); - } - Tcl_DeleteHashEntry(hePtr); } /* @@ -2454,11 +2286,9 @@ SetLambdaFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ register Tcl_Obj *objPtr) /* The object to convert. */ { - Interp *iPtr = (Interp *) interp; const char *name; Tcl_Obj *argsPtr, *bodyPtr, *nsObjPtr, **objv; - int isNew, objc, result; - CmdFrame *cfPtr = NULL; + int objc, result; Proc *procPtr; if (interp == NULL) { @@ -2504,93 +2334,6 @@ SetLambdaFromAny( procPtr->cmdPtr = NULL; /* - * TIP #280: Remember the line the apply body is starting on. In a Byte - * code context we ask the engine to provide us with the necessary - * information. This is for the initialization of the byte code compiler - * when the body is used for the first time. - * - * NOTE: The body is the second word in the 'objPtr'. Its location, - * accessible through 'context.line[1]' (see below) is therefore only the - * first approximation of the actual line the body is on. We have to use - * the string rep of the 'objPtr' to determine the exact line. This is - * available already through 'name'. Use 'TclListLines', see 'switch' - * (tclCmdMZ.c). - * - * This code is nearly identical to the #280 code in Tcl_ProcObjCmd, see - * this file. The differences are the different index of the body in the - * line array of the context, and the special processing mentioned in the - * previous paragraph to track into the list. Find a way to factor the - * common elements into a single function. - */ - - if (iPtr->cmdFramePtr) { - CmdFrame *contextPtr = TclStackAlloc(interp, sizeof(CmdFrame)); - - *contextPtr = *iPtr->cmdFramePtr; - if (contextPtr->type == TCL_LOCATION_BC) { - /* - * Retrieve the source context from the bytecode. This call - * accounts for the reference to the source file, if any, held in - * 'context.data.eval.path'. - */ - - TclGetSrcInfoForPc(contextPtr); - } else if (contextPtr->type == TCL_LOCATION_SOURCE) { - /* - * We created a new reference to the source file path name when we - * created 'context' above. Account for the reference. - */ - - Tcl_IncrRefCount(contextPtr->data.eval.path); - - } - - if (contextPtr->type == TCL_LOCATION_SOURCE) { - /* - * We can record source location within a lambda only if the body - * was not created by substitution. - */ - - if (contextPtr->line - && (contextPtr->nline >= 2) && (contextPtr->line[1] >= 0)) { - int buf[2]; - - /* - * Move from approximation (line of list cmd word) to actual - * location (line of 2nd list element). - */ - - cfPtr = ckalloc(sizeof(CmdFrame)); - TclListLines(objPtr, contextPtr->line[1], 2, buf, NULL); - - cfPtr->level = -1; - cfPtr->type = contextPtr->type; - cfPtr->line = ckalloc(sizeof(int)); - cfPtr->line[0] = buf[1]; - cfPtr->nline = 1; - cfPtr->framePtr = NULL; - cfPtr->nextPtr = NULL; - - cfPtr->data.eval.path = contextPtr->data.eval.path; - Tcl_IncrRefCount(cfPtr->data.eval.path); - - cfPtr->cmd = NULL; - cfPtr->len = 0; - } - - /* - * 'contextPtr' is going out of scope. Release the reference that - * it's holding to the source file path - */ - - Tcl_DecrRefCount(contextPtr->data.eval.path); - } - TclStackFree(interp, contextPtr); - } - Tcl_SetHashValue(Tcl_CreateHashEntry(iPtr->linePBodyPtr, procPtr, - &isNew), cfPtr); - - /* * Set the namespace for this lambda: given by objv[2] understood as a * global reference, or else global per default. */ @@ -2728,22 +2471,6 @@ TclNRApplyObjCmd( procPtr->cmdPtr = &extraPtr->cmd; extraPtr->cmd.nsPtr = (Namespace *) nsPtr; - /* - * TIP#280 (semi-)HACK! - * - * Using cmd.clientData to tell [info frame] how to render the lambdaPtr. - * The InfoFrameCmd will detect this case by testing cmd.hPtr for NULL. - * This condition holds here because of the memset() above, and nowhere - * else (in the core). Regular commands always have a valid hPtr, and - * lambda's never. - */ - - extraPtr->efi.length = 1; - extraPtr->efi.fields[0].name = "lambda"; - extraPtr->efi.fields[0].proc = NULL; - extraPtr->efi.fields[0].clientData = lambdaPtr; - extraPtr->cmd.clientData = &extraPtr->efi; - isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL); if (isRootEnsemble) { iPtr->ensembleRewrite.sourceObjs = objv; diff --git a/generic/tclResult.c b/generic/tclResult.c index a1f307c..e8b88fa 100644 --- a/generic/tclResult.c +++ b/generic/tclResult.c @@ -17,7 +17,7 @@ enum returnKeys { KEY_CODE, KEY_ERRORCODE, KEY_ERRORINFO, KEY_ERRORLINE, - KEY_LEVEL, KEY_OPTIONS, KEY_ERRORSTACK, KEY_LAST + KEY_LEVEL, KEY_OPTIONS, KEY_LAST }; /* @@ -43,8 +43,6 @@ typedef struct InterpState { Tcl_Obj *errorCode; Tcl_Obj *returnOpts; Tcl_Obj *objResult; - Tcl_Obj *errorStack; - int resetErrorStack; } InterpState; /* @@ -81,8 +79,6 @@ Tcl_SaveInterpState( statePtr->returnLevel = iPtr->returnLevel; statePtr->returnCode = iPtr->returnCode; statePtr->errorInfo = iPtr->errorInfo; - statePtr->errorStack = iPtr->errorStack; - statePtr->resetErrorStack = iPtr->resetErrorStack; if (statePtr->errorInfo) { Tcl_IncrRefCount(statePtr->errorInfo); } @@ -94,9 +90,6 @@ Tcl_SaveInterpState( if (statePtr->returnOpts) { Tcl_IncrRefCount(statePtr->returnOpts); } - if (statePtr->errorStack) { - Tcl_IncrRefCount(statePtr->errorStack); - } statePtr->objResult = Tcl_GetObjResult(interp); Tcl_IncrRefCount(statePtr->objResult); return (Tcl_InterpState) statePtr; @@ -134,7 +127,6 @@ Tcl_RestoreInterpState( iPtr->returnLevel = statePtr->returnLevel; iPtr->returnCode = statePtr->returnCode; - iPtr->resetErrorStack = statePtr->resetErrorStack; if (iPtr->errorInfo) { Tcl_DecrRefCount(iPtr->errorInfo); } @@ -149,13 +141,6 @@ Tcl_RestoreInterpState( if (iPtr->errorCode) { Tcl_IncrRefCount(iPtr->errorCode); } - if (iPtr->errorStack) { - Tcl_DecrRefCount(iPtr->errorStack); - } - iPtr->errorStack = statePtr->errorStack; - if (iPtr->errorStack) { - Tcl_IncrRefCount(iPtr->errorStack); - } if (iPtr->returnOpts) { Tcl_DecrRefCount(iPtr->returnOpts); } @@ -200,9 +185,6 @@ Tcl_DiscardInterpState( if (statePtr->returnOpts) { Tcl_DecrRefCount(statePtr->returnOpts); } - if (statePtr->errorStack) { - Tcl_DecrRefCount(statePtr->errorStack); - } Tcl_DecrRefCount(statePtr->objResult); ckfree(statePtr); } @@ -561,7 +543,6 @@ Tcl_ResetResult( Tcl_DecrRefCount(iPtr->errorInfo); iPtr->errorInfo = NULL; } - iPtr->resetErrorStack = 1; iPtr->returnLevel = 1; iPtr->returnCode = TCL_OK; if (iPtr->returnOpts) { @@ -798,7 +779,6 @@ GetKeys(void) TclNewLiteralStringObj(keys[KEY_ERRORCODE], "-errorcode"); TclNewLiteralStringObj(keys[KEY_ERRORINFO], "-errorinfo"); TclNewLiteralStringObj(keys[KEY_ERRORLINE], "-errorline"); - TclNewLiteralStringObj(keys[KEY_ERRORSTACK],"-errorstack"); TclNewLiteralStringObj(keys[KEY_LEVEL], "-level"); TclNewLiteralStringObj(keys[KEY_OPTIONS], "-options"); @@ -905,40 +885,6 @@ TclProcessReturn( iPtr->flags |= ERR_ALREADY_LOGGED; } } - Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORSTACK], - &valuePtr); - if (valuePtr != NULL) { - int len, valueObjc; - Tcl_Obj **valueObjv; - - if (Tcl_IsShared(iPtr->errorStack)) { - Tcl_Obj *newObj; - - newObj = Tcl_DuplicateObj(iPtr->errorStack); - Tcl_DecrRefCount(iPtr->errorStack); - Tcl_IncrRefCount(newObj); - iPtr->errorStack = newObj; - } - - /* - * List extraction done after duplication to avoid moving the rug - * if someone does [return -errorstack [info errorstack]] - */ - - if (Tcl_ListObjGetElements(interp, valuePtr, &valueObjc, - &valueObjv) == TCL_ERROR) { - return TCL_ERROR; - } - iPtr->resetErrorStack = 0; - Tcl_ListObjLength(interp, iPtr->errorStack, &len); - - /* - * Reset while keeping the list intrep as much as possible. - */ - - Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, valueObjc, - valueObjv); - } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORCODE], &valuePtr); if (valuePtr != NULL) { @@ -1103,40 +1049,6 @@ TclMergeReturnOptions( } /* - * Check for bogus -errorstack value. - */ - - Tcl_DictObjGet(NULL, returnOpts, keys[KEY_ERRORSTACK], &valuePtr); - if (valuePtr != NULL) { - int length; - - if (TCL_ERROR == Tcl_ListObjLength(NULL, valuePtr, &length )) { - /* - * Value is not a list, which is illegal for -errorstack. - */ - - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad -errorstack value: expected a list but got \"%s\"", - TclGetString(valuePtr))); - Tcl_SetErrorCode(interp, "TCL", "RESULT", "NONLIST_ERRORSTACK", - NULL); - goto error; - } - if (length % 2) { - /* - * Errorstack must always be an even-sized list - */ - - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "forbidden odd-sized list for -errorstack: \"%s\"", - TclGetString(valuePtr))); - Tcl_SetErrorCode(interp, "TCL", "RESULT", - "ODDSIZEDLIST_ERRORSTACK", NULL); - goto error; - } - } - - /* * Convert [return -code return -level X] to [return -code ok -level X+1] */ @@ -1213,7 +1125,6 @@ Tcl_GetReturnOptions( if (result == TCL_ERROR) { Tcl_AddErrorInfo(interp, ""); - Tcl_DictObjPut(NULL, options, keys[KEY_ERRORSTACK], iPtr->errorStack); } if (iPtr->errorCode) { Tcl_DictObjPut(NULL, options, keys[KEY_ERRORCODE], iPtr->errorCode); @@ -1229,31 +1140,6 @@ Tcl_GetReturnOptions( /* *------------------------------------------------------------------------- * - * TclNoErrorStack -- - * - * Removes the -errorstack entry from an options dict to avoid reference - * cycles. - * - * Results: - * The (unshared) argument options dict, modified in -place. - * - *------------------------------------------------------------------------- - */ - -Tcl_Obj * -TclNoErrorStack( - Tcl_Interp *interp, - Tcl_Obj *options) -{ - Tcl_Obj **keys = GetKeys(); - - Tcl_DictObjRemove(interp, options, keys[KEY_ERRORSTACK]); - return options; -} - -/* - *------------------------------------------------------------------------- - * * Tcl_SetReturnOptions -- * * Accepts an interp and a dictionary of return options, and sets the diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 7093136..d0c10a4 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -540,8 +540,8 @@ static const TclIntStubs tclIntStubs = { TclPtrMakeUpvar, /* 229 */ TclObjLookupVar, /* 230 */ TclGetNamespaceFromObj, /* 231 */ - TclEvalObjEx, /* 232 */ - TclGetSrcInfoForPc, /* 233 */ + 0, /* 232 */ + 0, /* 233 */ TclVarHashCreateVar, /* 234 */ TclInitVarHashTable, /* 235 */ TclBackgroundException, /* 236 */ diff --git a/generic/tclTest.c b/generic/tclTest.c index dbf6efa..8125289 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -6559,7 +6559,7 @@ TestNRELevels( Interp *iPtr = (Interp *) interp; static ptrdiff_t *refDepth = NULL; ptrdiff_t depth; - Tcl_Obj *levels[6]; + Tcl_Obj *levels[5]; int i = 0; NRE_callback *cbPtr = iPtr->execEnvPtr->callbackPtr; @@ -6571,18 +6571,17 @@ TestNRELevels( levels[0] = Tcl_NewIntObj(depth); levels[1] = Tcl_NewIntObj(iPtr->numLevels); - levels[2] = Tcl_NewIntObj(iPtr->cmdFramePtr->level); - levels[3] = Tcl_NewIntObj(iPtr->varFramePtr->level); - levels[4] = Tcl_NewIntObj(iPtr->execEnvPtr->execStackPtr->tosPtr + levels[2] = Tcl_NewIntObj(iPtr->varFramePtr->level); + levels[3] = Tcl_NewIntObj(iPtr->execEnvPtr->execStackPtr->tosPtr - iPtr->execEnvPtr->execStackPtr->stackWords); while (cbPtr) { i++; cbPtr = NEXT_CB(cbPtr); } - levels[5] = Tcl_NewIntObj(i); + levels[4] = Tcl_NewIntObj(i); - Tcl_SetObjResult(interp, Tcl_NewListObj(6, levels)); + Tcl_SetObjResult(interp, Tcl_NewListObj(5, levels)); return TCL_OK; } diff --git a/generic/tclVar.c b/generic/tclVar.c index 451ef7b..3abec04 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -1839,9 +1839,6 @@ TclPtrSetVar( } else { if (Tcl_IsShared(oldValuePtr)) { /* Append to copy. */ varPtr->value.objPtr = Tcl_DuplicateObj(oldValuePtr); - - TclContinuationsCopy(varPtr->value.objPtr, oldValuePtr); - TclDecrRefCount(oldValuePtr); oldValuePtr = varPtr->value.objPtr; Tcl_IncrRefCount(oldValuePtr); /* Since var is ref */ diff --git a/tests/cmdMZ.test b/tests/cmdMZ.test index 2d68138..477101b 100644 --- a/tests/cmdMZ.test +++ b/tests/cmdMZ.test @@ -151,7 +151,7 @@ test cmdMZ-return-2.10 {return option handling} -body { list [catch {return -level 0 -code error} -> foo] [dictSort $foo] } -match glob -result {1 {-code 1 -errorcode NONE -errorinfo { while executing -"return -level 0 -code error"} -errorline 1 -errorstack * -level 0}} +"return -level 0 -code error"} -errorline 1 -level 0}} test cmdMZ-return-2.11 {return option handling} { list [catch {return -level 0 -code break} -> foo] [dictSort $foo] } {3 {-code 3 -level 0}} @@ -187,9 +187,9 @@ test cmdMZ-return-2.17 {return opton handling} { } {1 c {a b}} test cmdMZ-return-2.18 {return option handling} { list [catch { - return -code error -errorstack [list CALL a CALL b] yo - } -> foo] [dictSort $foo] [info errorstack] -} {2 {-code 1 -errorcode NONE -errorstack {CALL a CALL b} -level 1} {CALL a CALL b}} + return -code error yo + } -> foo] [dictSort $foo] +} {2 {-code 1 -errorcode NONE -level 1}} # Check that the result of a [return -options $opts $result] is # indistinguishable from that of the originally caught script, no matter what @@ -208,7 +208,7 @@ foreach {testid script} { cmdMZ-return-3.10 {return -code error -errorinfo foo} cmdMZ-return-3.11 {return -code error -errorinfo foo -errorcode bar} cmdMZ-return-3.12 {return -code error -errorinfo foo -errorcode bar -errorline 10} - cmdMZ-return-3.12.1 {return -code error -errorinfo foo -errorcode bar -errorline 10 -errorstack baz} + cmdMZ-return-3.12.1 {return -code error -errorinfo foo -errorcode bar -errorline 10} cmdMZ-return-3.13 {return -options {x y z 2}} cmdMZ-return-3.14 {return -level 3 -code break sdf} } { diff --git a/tests/coroutine.test b/tests/coroutine.test index 205da67..baf97da 100644 --- a/tests/coroutine.test +++ b/tests/coroutine.test @@ -285,18 +285,18 @@ test coroutine-3.1 {info level computation} -setup { rename a {} rename b {} } -result {1 1 1} -test coroutine-3.2 {info frame computation} -setup { - proc a {} {while 1 {yield [info frame]}} - proc b {} foo -} -body { - set l0 [coroutine foo a] - set l1 [foo] - set l2 [b] - expr {$l2 - $l1} -} -cleanup { - rename a {} - rename b {} -} -result 1 +#test coroutine-3.2 {info frame computation} -setup { +# proc a {} {while 1 {yield [info frame]}} +# proc b {} foo +#} -body { +# set l0 [coroutine foo a] +# set l1 [foo] +# set l2 [b] +# expr {$l2 - $l1} +#} -cleanup { +# rename a {} +# rename b {} +#} -result 1 test coroutine-3.3 {info coroutine} -setup { proc a {} {info coroutine} proc b {} a @@ -324,27 +324,27 @@ test coroutine-3.5 {info coroutine} -setup { rename a {} rename b {} } -result {} -test coroutine-3.6 {info frame, bug #2910094} -setup { - proc stack {} { - set res [list "LEVEL:[set lev [info frame]]"] - for {set i 1} {$i < $lev} {incr i} { - lappend res [info frame $i] - } - set res - # the precise command depends on line numbers and such, is likely not - # to be stable: just check that the test completes! - return - } - proc a {} stack -} -body { - coroutine aa a -} -cleanup { - rename stack {} - rename a {} -} -result {} -test coroutine-3.7 {bug 0b874c344d} { - dict get [coroutine X coroutine Y info frame 0] cmd -} {coroutine X coroutine Y info frame 0} +#test coroutine-3.6 {info frame, bug #2910094} -setup { +# proc stack {} { +# set res [list "LEVEL:[set lev [info frame]]"] +# for {set i 1} {$i < $lev} {incr i} { +# lappend res [info frame $i] +# } +# set res +# # the precise command depends on line numbers and such, is likely not +# # to be stable: just check that the test completes! +# return +# } +# proc a {} stack +#} -body { +# coroutine aa a +#} -cleanup { +# rename stack {} +# rename a {} +#} -result {} +#test coroutine-3.7 {bug 0b874c344d} { +# dict get [coroutine X coroutine Y info frame 0] cmd +#} {coroutine X coroutine Y info frame 0} test coroutine-4.1 {bug #2093188} -setup { proc foo {} { diff --git a/tests/dict.test b/tests/dict.test index d5406d0..86a44f8 100644 --- a/tests/dict.test +++ b/tests/dict.test @@ -1665,56 +1665,56 @@ test dict-22.23 {dict with: compiled} { }} } 1,2 -proc linenumber {} { - dict get [info frame -1] line -} -test dict-23.1 {dict compilation crash: Bug 3487626} { - apply {{} {apply {n { - set e {} - set k {} - dict for {a b} {c {d {e {f g}}}} { - ::tcl::dict::for {h i} $b { - dict update i e j { - ::tcl::dict::update j f k { - return [expr {$n - [linenumber]}] - } - } - } - } - }} [linenumber]}} -} 5 -test dict-23.2 {dict compilation crash: Bug 3487626} { - # Something isn't quite right in line number and continuation line - # tracking; at time of writing, this test produces 7, not 5, which - # indicates that the extra newlines in the non-script argument are - # confusing things. - apply {{} {apply {n { - set e {} - set k {} - dict for {a { -b -}} {c {d {e {f g}}}} { - ::tcl::dict::for {h { -i -}} ${ -b -} { - dict update { -i -} e { -j -} { - ::tcl::dict::update { -j -} f k { - return [expr {$n - [linenumber]}] - } - } - } - } - }} [linenumber]}} -} 5 -rename linenumber {} +#proc linenumber {} { +# dict get [info frame -1] line +#} +#test dict-23.1 {dict compilation crash: Bug 3487626} { +# apply {{} {apply {n { +# set e {} +# set k {} +# dict for {a b} {c {d {e {f g}}}} { +# ::tcl::dict::for {h i} $b { +# dict update i e j { +# ::tcl::dict::update j f k { +# return [expr {$n - [linenumber]}] +# } +# } +# } +# } +# }} [linenumber]}} +#} 5 +#test dict-23.2 {dict compilation crash: Bug 3487626} { +# # Something isn't quite right in line number and continuation line +# # tracking; at time of writing, this test produces 7, not 5, which +# # indicates that the extra newlines in the non-script argument are +# # confusing things. +# apply {{} {apply {n { +# set e {} +# set k {} +# dict for {a { +#b +#}} {c {d {e {f g}}}} { +# ::tcl::dict::for {h { +#i +#}} ${ +#b +#} { +# dict update { +#i +#} e { +#j +#} { +# ::tcl::dict::update { +#j +#} f k { +# return [expr {$n - [linenumber]}] +# } +# } +# } +# } +# }} [linenumber]}} +#} 5 +#rename linenumber {} test dict-24.1 {dict map command: syntax} -returnCodes error -body { dict map @@ -1899,123 +1899,123 @@ test dict-24.20 {dict map stack space compilation: 'dict for' bug 1903325} { concat "c=$y,$args" }} {} 1 2 3 } {c=1,2 3} -proc linenumber {} { - dict get [info frame -1] line -} -test dict-24.20.1 {dict compilation crash: 'dict for' bug 3487626} { - apply {{} {apply {n { - set e {} - set k {} - dict map {a b} {c {d {e {f g}}}} { - ::tcl::dict::map {h i} $b { - dict update i e j { - ::tcl::dict::update j f k { - return [expr {$n - [linenumber]}] - } - } - } - } - }} [linenumber]}} -} 5 -test dict-24.21 {dict compilation crash: 'dict for' bug 3487626} { - apply {{} {apply {n { - set e {} - set k {} - dict map {a { -b -}} {c {d {e {f g}}}} { - ::tcl::dict::map {h { -i -}} ${ -b -} { - dict update { -i -} e { -j -} { - ::tcl::dict::update { -j -} f k { - return [expr {$n - [linenumber]}] - } - } - } - } - }} [linenumber]}} -} 5 +#proc linenumber {} { +# dict get [info frame -1] line +#} +#test dict-24.20.1 {dict compilation crash: 'dict for' bug 3487626} { +# apply {{} {apply {n { +# set e {} +# set k {} +# dict map {a b} {c {d {e {f g}}}} { +# ::tcl::dict::map {h i} $b { +# dict update i e j { +# ::tcl::dict::update j f k { +# return [expr {$n - [linenumber]}] +# } +# } +# } +# } +# }} [linenumber]}} +#} 5 +#test dict-24.21 {dict compilation crash: 'dict for' bug 3487626} { +# apply {{} {apply {n { +# set e {} +# set k {} +# dict map {a { +#b +#}} {c {d {e {f g}}}} { +# ::tcl::dict::map {h { +#i +#}} ${ +#b +#} { +# dict update { +#i +#} e { +#j +#} { +# ::tcl::dict::update { +#j +#} f k { +# return [expr {$n - [linenumber]}] +# } +# } +# } +# } +# }} [linenumber]}} +#} 5 test dict-23.3 {CompileWord OBOE} { # segfault when buggy apply {{} {tcl::dict::lappend foo bar \ [format baz]}} } {bar baz} -test dict-23.4 {CompileWord OBOE} { - apply {n { - dict set foo {*}{ - } [return [incr n -[linenumber]]] val - }} [linenumber] -} 1 +#test dict-23.4 {CompileWord OBOE} { +# apply {n { +# dict set foo {*}{ +# } [return [incr n -[linenumber]]] val +# }} [linenumber] +#} 1 test dict-23.5 {CompileWord OBOE} { # segfault when buggy apply {{} {tcl::dict::incr foo \ [format bar]}} } {bar 1} -test dict-23.6 {CompileWord OBOE} { - apply {n { - dict get {a b} {*}{ - } [return [incr n -[linenumber]]] - }} [linenumber] -} 1 -test dict-23.7 {CompileWord OBOE} { - apply {n { - dict for {a b} [return [incr n -[linenumber]]] {*}{ - } {} - }} [linenumber] -} 2 -test dict-23.8 {CompileWord OBOE} { - apply {n { - dict update foo {*}{ - } [return [incr n -[linenumber]]] x {} - }} [linenumber] -} 1 -test dict-23.9 {CompileWord OBOE} { - apply {n { - dict exists {} {*}{ - } [return [incr n -[linenumber]]] - }} [linenumber] -} 1 -test dict-23.10 {CompileWord OBOE} { - apply {n { - dict with foo {*}{ - } [return [incr n -[linenumber]]] {} - }} [linenumber] -} 1 -test dict-23.11 {CompileWord OBOE} { - apply {n { - dict with ::foo {*}{ - } [return [incr n -[linenumber]]] {} - }} [linenumber] -} 1 -test dict-23.12 {CompileWord OBOE} { - apply {n { - dict with {*}{ - } [return [incr n -[linenumber]]] {} - }} [linenumber] -} 1 -test dict-23.13 {CompileWord OBOE} { - apply {n { - dict with {*}{ - } [return [incr n -[linenumber]]] {bar} - }} [linenumber] -} 1 -test dict-23.14 {CompileWord OBOE} { - apply {n { - dict with foo {*}{ - } [return [incr n -[linenumber]]] {bar} - }} [linenumber] -} 1 +#test dict-23.6 {CompileWord OBOE} { +# apply {n { +# dict get {a b} {*}{ +# } [return [incr n -[linenumber]]] +# }} [linenumber] +#} 1 +#test dict-23.7 {CompileWord OBOE} { +# apply {n { +# dict for {a b} [return [incr n -[linenumber]]] {*}{ +# } {} +# }} [linenumber] +#} 2 +#test dict-23.8 {CompileWord OBOE} { +# apply {n { +# dict update foo {*}{ +# } [return [incr n -[linenumber]]] x {} +# }} [linenumber] +#} 1 +#test dict-23.9 {CompileWord OBOE} { +# apply {n { +# dict exists {} {*}{ +# } [return [incr n -[linenumber]]] +# }} [linenumber] +#} 1 +#test dict-23.10 {CompileWord OBOE} { +# apply {n { +# dict with foo {*}{ +# } [return [incr n -[linenumber]]] {} +# }} [linenumber] +#} 1 +#test dict-23.11 {CompileWord OBOE} { +# apply {n { +# dict with ::foo {*}{ +# } [return [incr n -[linenumber]]] {} +# }} [linenumber] +#} 1 +#test dict-23.12 {CompileWord OBOE} { +# apply {n { +# dict with {*}{ +# } [return [incr n -[linenumber]]] {} +# }} [linenumber] +#} 1 +#test dict-23.13 {CompileWord OBOE} { +# apply {n { +# dict with {*}{ +# } [return [incr n -[linenumber]]] {bar} +# }} [linenumber] +#} 1 +#test dict-23.14 {CompileWord OBOE} { +# apply {n { +# dict with foo {*}{ +# } [return [incr n -[linenumber]]] {bar} +# }} [linenumber] +#} 1 +#rename linenumber {} -rename linenumber {} test dict-24.22 {dict map results (non-compiled)} { dict map {k v} [dict map {k v} {a 1 b 2 c 3 d 4} { list $v $k }] { return -level 0 "$k,$v" diff --git a/tests/error.test b/tests/error.test index af07ed7..cb85a11 100644 --- a/tests/error.test +++ b/tests/error.test @@ -170,28 +170,28 @@ test error-4.5 {errorInfo and errorCode variables} { list [catch {error msg1 msg2 {}} msg] $msg $::errorInfo $::errorCode } {1 msg1 msg2 {}} -test error-4.6 {errorstack via info } -body { - proc f x {g $x$x} - proc g x {error G:$x} - catch {f 12} - info errorstack -} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1} -test error-4.7 {errorstack via options dict } -body { - proc f x {g $x$x} - proc g x {error G:$x} - catch {f 12} m d - dict get $d -errorstack -} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1} -test error-4.8 {errorstack from exec traces} -body { - proc foo args {} - proc goo {} foo - trace add execution foo enter {error bar;#} - catch goo m d - dict get $d -errorstack -} -cleanup { - rename goo {}; rename foo {} - unset -nocomplain m d -} -result {INNER {error bar} CALL goo UP 1} +#test error-4.6 {errorstack via info } -body { +# proc f x {g $x$x} +# proc g x {error G:$x} +# catch {f 12} +# info errorstack +#} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1} +#test error-4.7 {errorstack via options dict } -body { +# proc f x {g $x$x} +# proc g x {error G:$x} +# catch {f 12} m d +# dict get $d -errorstack +#} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1} +#test error-4.8 {errorstack from exec traces} -body { +# proc foo args {} +# proc goo {} foo +# trace add execution foo enter {error bar;#} +# catch goo m d +# dict get $d -errorstack +#} -cleanup { +# rename goo {}; rename foo {} +# unset -nocomplain m d +#} -result {INNER {error bar} CALL goo UP 1} # Errors in error command itself @@ -247,15 +247,15 @@ test error-6.9 {catch must reset error state} { catch foo list $::errorCode } {NONE} -test error-6.10 {catch must reset errorstack} -body { - proc f x {g $x$x} - proc g x {error G:$x} - catch {f 12} - set e1 [info errorstack] - catch {f 13} - set e2 [info errorstack] - list $e1 $e2 -} -match glob -result {{INNER * CALL {g 1212} CALL {f 12} UP 1} {INNER * CALL {g 1313} CALL {f 13} UP 1}} +#test error-6.10 {catch must reset errorstack} -body { +# proc f x {g $x$x} +# proc g x {error G:$x} +# catch {f 12} +# set e1 [info errorstack] +# catch {f 13} +# set e2 [info errorstack] +# list $e1 $e2 +#} -match glob -result {{INNER * CALL {g 1212} CALL {f 12} UP 1} {INNER * CALL {g 1313} CALL {f 13} UP 1}} test error-7.1 {Bug 1397843} -body { variable cmds diff --git a/tests/execute.test b/tests/execute.test index 9a2ffbd..e51251a 100644 --- a/tests/execute.test +++ b/tests/execute.test @@ -972,7 +972,7 @@ test execute-8.5 {Bug 2038069} -setup { demo } -cleanup { rename demo {} -} -match glob -result {-code 1 -level 0 -errorstack * -errorcode NONE -errorinfo {FOO +} -match glob -result {-code 1 -level 0 -errorcode NONE -errorinfo {FOO while executing "error FOO" invoked from within @@ -1057,15 +1057,15 @@ test execute-11.2 {Bug 268b23df11} -setup { rename crash {} rename zero {} } -result 0 -test execute-11.3 {Bug a0ece9d6d4} -setup { - proc crash {} {expr {rand()}} - trace add execution crash enterstep {apply {args {info frame -2}}} -} -body { - string is double [crash] -} -cleanup { - trace remove execution crash enterstep {apply {args {info frame -2}}} - rename crash {} -} -result 1 +#test execute-11.3 {Bug a0ece9d6d4} -setup { +# proc crash {} {expr {rand()}} +# trace add execution crash enterstep {apply {args {info frame -2}}} +#} -body { +# string is double [crash] +#} -cleanup { +# trace remove execution crash enterstep {apply {args {info frame -2}}} +# rename crash {} +#} -result 1 # cleanup if {[info commands testobj] != {}} { diff --git a/tests/for.test b/tests/for.test index 1a65274..2e86548 100644 --- a/tests/for.test +++ b/tests/for.test @@ -690,7 +690,7 @@ test for-6.9 {Tcl_ForObjCmd: error executing command body} -body { } -match glob -result {wrong # args: should be "set varName ?newValue?" while *ing "set" - ("for" body line 1) + (loop body line 1) invoked from within "$z {set i 0} {$i < 5} {incr i} {set}"} test for-6.10 {Tcl_ForObjCmd: simple command body} { diff --git a/tests/foreach.test b/tests/foreach.test index 6fd5476..47cb095 100644 --- a/tests/foreach.test +++ b/tests/foreach.test @@ -254,16 +254,16 @@ test foreach-9.1 {compiled empty var list} { list [catch { foo } msg] $msg } {1 {foreach varlist is empty}} -test foreach-9.2 {line numbers} -setup { - proc linenumber {} {dict get [info frame -1] line} -} -body { - apply {n { - foreach x y {*}{ - } {return [incr n -[linenumber]]} - }} [linenumber] -} -cleanup { - rename linenumber {} -} -result 1 +#test foreach-9.2 {line numbers} -setup { +# proc linenumber {} {dict get [info frame -1] line} +#} -body { +# apply {n { +# foreach x y {*}{ +# } {return [incr n -[linenumber]]} +# }} [linenumber] +#} -cleanup { +# rename linenumber {} +#} -result 1 test foreach-10.1 {foreach: [Bug 1671087]} -setup { proc demo {} { diff --git a/tests/info.test b/tests/info.test index e67202b..90a6c42 100644 --- a/tests/info.test +++ b/tests/info.test @@ -678,1727 +678,22 @@ test info-21.1 {miscellaneous error conditions} -returnCodes error -body { } -result {wrong # args: should be "info subcommand ?arg ...?"} test info-21.2 {miscellaneous error conditions} -returnCodes error -body { info gorp -} -result {unknown or ambiguous subcommand "gorp": must be args, body, class, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} +} -result {unknown or ambiguous subcommand "gorp": must be args, body, class, commands, complete, coroutine, default, exists, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} test info-21.3 {miscellaneous error conditions} -returnCodes error -body { info c -} -result {unknown or ambiguous subcommand "c": must be args, body, class, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} +} -result {unknown or ambiguous subcommand "c": must be args, body, class, commands, complete, coroutine, default, exists, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} test info-21.4 {miscellaneous error conditions} -returnCodes error -body { info l -} -result {unknown or ambiguous subcommand "l": must be args, body, class, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} +} -result {unknown or ambiguous subcommand "l": must be args, body, class, commands, complete, coroutine, default, exists, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} test info-21.5 {miscellaneous error conditions} -returnCodes error -body { info s -} -result {unknown or ambiguous subcommand "s": must be args, body, class, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} +} -result {unknown or ambiguous subcommand "s": must be args, body, class, commands, complete, coroutine, default, exists, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} -## -# ### ### ### ######### ######### ######### -## info frame +# removed [info frame] tests: 22.0 to 33.35 -## Helper -# For the more complex results we cut the file name down to remove path -# dependencies, and we use only part of the first line of the reported -# command. The latter is required because otherwise the whole test case may -# appear in some results, but the result is part of the testcase. An infinite -# string would be required to describe that. The cutting-down breaks this. - -proc reduce {frame} { - set cmd [dict get $frame cmd] - if {[regexp \n $cmd]} { - dict set frame cmd \ - [string range [lindex [split $cmd \n] 0] 0 end-4] - } - if {[dict exists $frame file]} { - dict set frame file \ - [file tail [dict get $frame file]] - } - return $frame -} - -proc subinterp {} { interp create sub ; interp debug sub -frame 1; - interp eval sub [list proc reduce [info args reduce] [info body reduce]] -} - -## Helper -# Generate a stacktrace from the current location to top. This code -# not only depends on the exact location of things, but also on the -# implementation of tcltest. Any changes and these tests will have to -# be updated. - -proc etrace {} { - set res {} - set level [info frame] - while {$level} { - lappend res [list $level [reduce [info frame $level]]] - incr level -1 - } - return $res -} - -test info-22.0 {info frame, levels} {!singleTestInterp} { - info frame -} 7 -test info-22.1 {info frame, bad level relative} {!singleTestInterp} { - # catch is another level!, i.e. we have 8, not 7 - catch {info frame -8} msg - set msg -} {bad level "-8"} -test info-22.2 {info frame, bad level absolute} {!singleTestInterp} { - # catch is another level!, i.e. we have 8, not 7 - catch {info frame 9} msg - set msg -} {bad level "9"} -test info-22.3 {info frame, current, relative} -match glob -body { - info frame 0 -} -result {type source line 750 file */info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-22.4 {info frame, current, relative, nested} -match glob -body { - set res [info frame 0] -} -result {type source line 753 file */info.test cmd {info frame 0} proc ::tcltest::RunTest} -cleanup {unset res} -test info-22.5 {info frame, current, absolute} -constraints {!singleTestInterp} -match glob -body { - reduce [info frame 7] -} -result {type source line 756 file info.test cmd {info frame 7} proc ::tcltest::RunTest} -test info-22.6 {info frame, global, relative} {!singleTestInterp} { - reduce [info frame -6] -} {type source line 758 file info.test cmd test\ info-22.6\ \{info\ frame,\ global,\ relative\}\ \{!singleTestInter level 0} -test info-22.7 {info frame, global, absolute} {!singleTestInterp} { - reduce [info frame 1] -} {type source line 761 file info.test cmd test\ info-22.7\ \{info\ frame,\ global,\ absolute\}\ \{!singleTestInter level 0} -test info-22.8 {info frame, basic trace} -match glob -body { - join [lrange [etrace] 0 2] \n -} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} -* {type source line 765 file info.test cmd etrace proc ::tcltest::RunTest} -* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}} -unset -nocomplain msg - -test info-23.0.0 {eval'd info frame} {!singleTestInterp} { - eval {info frame} -} 8 -test info-23.0.1 {eval'd info frame} -constraints {singleTestInterp} -match glob -body { - eval {info frame} -} -result {1[12]} ;# SingleTestInterp results changes depending on running the whole suite, or info.test alone. -test info-23.1.0 {eval'd info frame, semi-dynamic} {!singleTestInterp} { - eval info frame -} 8 -test info-23.1.1 {eval'd info frame, semi-dynamic} -constraints {singleTestInterp} -match glob -body { - eval info frame -} -result {1[12]} -test info-23.2.0 {eval'd info frame, dynamic} -constraints {!singleTestInterp} -body { - set script {info frame} - eval $script -} -cleanup {unset script} -result 8 -test info-23.2.1 {eval'd info frame, dynamic} -constraints {singleTestInterp} -match glob -body { - set script {info frame} - eval $script -} -cleanup {unset script} -result {1[12]} -test info-23.3 {eval'd info frame, literal} -match glob -body { - eval { - info frame 0 - } -} -result {type source line 793 file * cmd {info frame 0} proc ::tcltest::RunTest} -test info-23.4 {eval'd info frame, semi-dynamic} { - eval info frame 0 -} {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest} -test info-23.5 {eval'd info frame, dynamic} -cleanup {unset script} -body { - set script {info frame 0} - eval $script -} -result {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest} -test info-23.6 {eval'd info frame, trace} -match glob -cleanup {unset script} -body { - set script {etrace} - join [lrange [eval $script] 0 2] \n -} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} -* {type eval line 1 cmd etrace proc ::tcltest::RunTest} -* {type source line 805 file info.test cmd {eval $script} proc ::tcltest::RunTest}} - -# ------------------------------------------------------------------------- - -# Procedures defined in scripts which are arguments to control -# structures (like 'namespace eval', 'interp eval', 'if', 'while', -# 'switch', 'catch', 'for', 'foreach', etc.) have no absolute -# location. The command implementations execute such scripts through -# Tcl_EvalObjEx. Flag 0 causes it to use the bytecode compiler. This -# causes the connection to the context to be lost. Currently only -# procedure bodies are able to remember their context. - -# NOTE THAT THESE DO NOT USE THE -setup OPTION TO [test] - -# ------------------------------------------------------------------------- - -namespace eval foo { - proc bar {} {info frame 0} -} - -test info-24.0 {info frame, interaction, namespace eval} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 825 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -set flag 1 -if {$flag} { - namespace eval foo {} - proc ::foo::bar {} {info frame 0} -} - -test info-24.1 {info frame, interaction, if} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 839 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -set flag 1 -while {$flag} { - namespace eval foo {} - proc ::foo::bar {} {info frame 0} - set flag 0 -};unset flag - -test info-24.2 {info frame, interaction, while} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 853 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -catch { - namespace eval foo {} - proc ::foo::bar {} {info frame 0} -} - -test info-24.3 {info frame, interaction, catch} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 867 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -foreach var val { - namespace eval foo {} - proc ::foo::bar {} {info frame 0} - break -}; unset var - -test info-24.4 {info frame, interaction, foreach} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 880 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -for {} {1} {} { - namespace eval foo {} - proc ::foo::bar {} {info frame 0} - break -} - -test info-24.5 {info frame, interaction, for} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 894 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -namespace eval foo {} -set x foo -switch -exact -- $x { - foo { - proc ::foo::bar {} {info frame 0} - } -} - -test info-24.6.0 {info frame, interaction, switch, list body} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo - unset x -} -result {type source line 910 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -namespace eval foo {} -set x foo -switch -exact -- $x foo { - proc ::foo::bar {} {info frame 0} -} - -test info-24.6.1 {info frame, interaction, switch, multi-body} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo - unset x -} -result {type source line 926 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -namespace eval foo {} -set x foo -switch -exact -- $x [list foo { - proc ::foo::bar {} {info frame 0} -}] - -test info-24.6.2 {info frame, interaction, switch, list body, dynamic} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo - unset x -} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -namespace eval foo {} -dict for {k v} {foo bar} { - proc ::foo::bar {} {info frame 0} -} - -test info-24.7 {info frame, interaction, dict for} { - reduce [foo::bar] -} {type source line 955 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo; unset k v - -# ------------------------------------------------------------------------- - -namespace eval foo {} -set thedict {foo bar} -dict with thedict { - proc ::foo::bar {} {info frame 0} -} - -test info-24.8 {info frame, interaction, dict with} { - reduce [foo::bar] -} {type source line 969 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo -unset thedict foo - -# ------------------------------------------------------------------------- - -namespace eval foo {} -dict filter {foo bar} script {k v} { - proc ::foo::bar {} {info frame 0} - set x 1 -}; unset k v x - -test info-24.9 {info frame, interaction, dict filter} { - reduce [foo::bar] -} {type source line 983 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo -#unset x - -# ------------------------------------------------------------------------- - -eval { - proc bar {} {info frame 0} -} - -test info-25.0 {info frame, proc in eval} { - reduce [bar] -} {type source line 997 file info.test cmd {info frame 0} proc ::bar level 0} -# Don't need to clean up yet... - -proc bar {} {info frame 0} - -test info-25.1 {info frame, regular proc} { - reduce [bar] -} {type source line 1005 file info.test cmd {info frame 0} proc ::bar level 0} - -rename bar {} - -# ------------------------------------------------------------------------- -# More info-30.x test cases at the end of the file. -test info-30.0 {bs+nl in literal words} -cleanup {unset res} -body { - if {1} { - set res \ - [reduce [info frame 0]];#1018 - } - return $res - # This was reporting line 3 instead of the correct 4 because the - # bs+nl combination is subst by the parser before the 'if' - # command, and the bcc, see the word. Fixed by recording the - # offsets of all bs+nl sequences in literal words, then using the - # information in the bcc and other places to bump line numbers when - # parsing over the location. Also affected: testcases 22.8 and 23.6. -} -result {type source line 1018 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -# ------------------------------------------------------------------------- -# See 24.0 - 24.5 for similar situations, using literal scripts. - -set body {set flag 0 - set a c - set res [info frame 0]} ;# line 3! - -test info-31.0 {ns eval, script in variable} -body {namespace eval foo {variable res {}} - namespace eval foo $body - return $foo::res -} -result {type eval line 3 cmd {info frame 0} level 0} -cleanup { - catch {namespace delete foo} -} -test info-31.1 {if, script in variable} -cleanup {unset res a flag} -body { - if 1 $body - return $res -} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest} - -test info-31.1a {if, script in variable} -cleanup {unset res a flag} -body { - if 1 then $body - return $res -} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest} - -test info-31.2 {while, script in variable} -cleanup {unset flag res a} -body { - set flag 1 - while {$flag} $body - return $res -} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest} - -# .3 - proc - scoping prevent return of result ... - -test info-31.4 {foreach, script in variable} -cleanup {unset var res a flag} -body { - foreach var val $body - set res -} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest} - -test info-31.5 {for, script in variable} -cleanup {unset flag res a} -body { - set flag 1 - for {} {$flag} {} $body - return $res -} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest} - -test info-31.6 {eval, script in variable} -cleanup {unset res a flag} -body { - eval $body - return $res -} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest} - -# ------------------------------------------------------------------------- - -set body { - foo { - proc ::foo::bar {} {info frame 0} - } -} - -namespace eval foo {} -set x foo -switch -exact -- $x $body; unset body - -test info-31.7 {info frame, interaction, switch, dynamic} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo - unset x -} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -set body { - proc ::foo::bar {} {info frame 0} -} - -namespace eval foo {} -eval $body - -test info-32.0 {info frame, dynamic procedure} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -namespace {*}{ - eval - foo - {proc bar {} {info frame 0}} -} -test info-33.0 {{*}, literal, direct} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 1115 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -namespace eval foo {} -proc foo::bar {} { - set flag 1 - if {*}{ - {$flag} - {info frame 0} - } -} -test info-33.1 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 1130 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- - -namespace {*}" - eval - foo - {proc bar {} {info frame 0}} -" -test info-33.2 {{*}, literal, direct} { - reduce [foo::bar] -} {type source line 1144 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo - -# ------------------------------------------------------------------------- - -namespace {*}"eval\nfoo\n{proc bar {} {info frame 0}}\n" - -test info-33.2a {{*}, literal, not simple, direct} { - reduce [foo::bar] -} {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo - -# ------------------------------------------------------------------------- - -namespace eval foo {} -proc foo::bar {} { - set flag 1 - if {*}" - {1} - {info frame 0} - " -} -test info-33.3 {{*}, literal, simple, bytecompiled} { - reduce [foo::bar] -} {type source line 1169 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo - -# ------------------------------------------------------------------------- - -namespace eval foo {} -proc foo::bar {} { - set flag 1 - if {*}"\n{1}\n{info frame 0}" -} -test info-33.3a {{*}, literal, not simple, bytecompiled} { - reduce [foo::bar] -} {type eval line 1 cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo - -# ------------------------------------------------------------------------- - -set body { - eval - foo - {proc bar {} { - info frame 0 - }} -} -namespace {*}$body -test info-34.0 {{*}, dynamic, direct} { - reduce [foo::bar] -} {type proc line 2 cmd {info frame 0} proc ::foo::bar level 0} - -unset body -namespace delete foo - -# ------------------------------------------------------------------------- - -namespace eval foo {} -set body { - {$flag} - {info frame 0} -} -proc foo::bar {} { - global body ; set flag 1 - if {*}$body -} -test info-34.1 {{*}, literal, bytecompiled} { - reduce [foo::bar] -} {type eval line 1 cmd {info frame 0} proc ::foo::bar level 0} - -unset body -namespace delete foo - -# ------------------------------------------------------------------------- - -proc foo {} { - apply { - {x y} - {info frame 0} - } 0 0 -} -test info-35.0 {apply, literal} { - reduce [foo] -} {type source line 1231 file info.test cmd {info frame 0} lambda { - {x y} - {info frame 0} - } level 0} -rename foo {} - -set lambda { - {x y} - {info frame 0} -} -test info-35.1 {apply, dynamic} { - reduce [apply $lambda 0 0] -} {type proc line 1 cmd {info frame 0} lambda { - {x y} - {info frame 0} -} level 0} -unset lambda - -# ------------------------------------------------------------------------- - -namespace eval foo {} -proc foo::bar {} { - dict for {k v} {foo bar} { - set x [info frame 0] - } - set x -} -test info-36.0 {info frame, dict for, bcc} -body { - reduce [foo::bar] -} -result {type source line 1259 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo - -# ------------------------------------------------------------------------- - -namespace eval foo {} -proc foo::bar {} { - set x foo - switch -exact -- $x { - foo {set y [info frame 0]} - } - set y -} - -test info-36.1.0 {switch, list literal, bcc} -body { - reduce [foo::bar] -} -result {type source line 1275 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo - -# ------------------------------------------------------------------------- - -namespace eval foo {} -proc foo::bar {} { - set x foo - switch -exact -- $x foo {set y [info frame 0]} - set y -} - -test info-36.1.1 {switch, multi-body literals, bcc} -body { - reduce [foo::bar] -} -result {type source line 1291 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -namespace delete foo - -# ------------------------------------------------------------------------- - -test info-37.0 {eval pure list, single line} -match glob -body { - # Basically, counting the newline in the word seen through $foo - # doesn't really make sense. It makes a bit of sense if the word - # would have been a string literal in the command list. - # - # Problem: At the point where we see the list elements we cannot - # distinguish the two cases, thus we cannot switch between - # count/not-count, it is has to be one or the other for all - # cases. Of the two possibilities miguel convinced me that 'not - # counting' is the more proper. - set foo {b - c} - set cmd [list foreach $foo {x y} { - set res [join [lrange [etrace] 0 2] \n] - break - }] - eval $cmd - return $res -} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} -* {type eval line 2 cmd etrace proc ::tcltest::RunTest} -* {type eval line 1 cmd foreac proc ::tcltest::RunTest}} -cleanup {unset foo cmd res b c} - -# ------------------------------------------------------------------------- - -# 6 cases. -## DV. direct-var - unchanged -## DPV direct-proc-var - ditto -## PPV proc-proc-var - ditto -## DL. direct-literal - now tracking absolute location -## DPL direct-proc-literal - ditto -## PPL proc-proc-literal - ditto -## ### ### ### ######### ######### #########" - -proc control {vv script} { - upvar 1 $vv var - return [uplevel 1 $script] -} - -proc datal {} { - control y { - set y PPL - etrace - } -} - -proc datav {} { - set script { - set y PPV - etrace - } - control y $script -} - -test info-38.1 {location information for uplevel, dv, direct-var} -match glob -body { - set script { - set y DV. - etrace - } - join [lrange [uplevel \#0 $script] 0 2] \n -} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} -* {type eval line 3 cmd etrace proc ::tcltest::RunTest} -* {type source line 1361 file info.test cmd {uplevel \\#0 $script} proc ::tcltest::RunTest}} -cleanup {unset script y} - -# 38.2 moved to bottom to not disturb other tests with the necessary changes to this one. - - - - - - - - -test info-38.3 {location information for uplevel, dpv, direct-proc-var} -match glob -body { - set script { - set y DPV - etrace - } - join [lrange [control y $script] 0 3] \n -} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} -* {type eval line 3 cmd etrace proc ::control} -* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control} -* {type source line 1380 file info.test cmd {control y $script} proc ::tcltest::RunTest}} -cleanup {unset script y} - -# 38.4 moved to bottom to not disturb other tests with the necessary changes to this one. - - - - - - - - - -test info-38.5 {location information for uplevel, ppv, proc-proc-var} -match glob -body { - join [lrange [datav] 0 4] \n -} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} -* {type eval line 3 cmd etrace proc ::control} -* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control} -* {type source line 1353 file info.test cmd {control y $script} proc ::datav level 1} -* {type source line 1397 file info.test cmd datav proc ::tcltest::RunTest}} - -# 38.6 moved to bottom to not disturb other tests with the necessary changes to this one. - - - - - - - -testConstraint testevalex [llength [info commands testevalex]] -test info-38.7 {location information for arg substitution} -constraints testevalex -match glob -body { - join [lrange [testevalex {return -level 0 [etrace]}] 0 3] \n -} -result {* {type source line 730 file info.test cmd {info frame \$level} proc ::etrace level 0} -* {type eval line 1 cmd etrace proc ::tcltest::RunTest} -* {type source line 1414 file info.test cmd {testevalex {return -level 0 \[etrace]}} proc ::tcltest::RunTest} -* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}} - -# ------------------------------------------------------------------------- -# literal sharing - -test info-39.0 {location information not confused by literal sharing} -body { - namespace eval ::foo {} - proc ::foo::bar {} { - lappend res {} - lappend res [reduce [eval {info frame 0}]] - lappend res [reduce [eval {info frame 0}]] - return $res - } - set res [::foo::bar] - namespace delete ::foo - join $res \n -} -cleanup {unset res} -result { -type source line 1427 file info.test cmd {info frame 0} proc ::foo::bar level 0 -type source line 1428 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -# Additional tests for info-30.*, handling of continuation lines (bs+nl sequences). - -test info-30.1 {bs+nl in literal words, procedure body, compiled} -body { - proc abra {} { - if {1} \ - { - return \ - [reduce [info frame 0]];# line 1446 - } - } - abra -} -cleanup { - rename abra {} -} -result {type source line 1446 file info.test cmd {info frame 0} proc ::abra level 0} - -test info-30.2 {bs+nl in literal words, namespace script} { - namespace eval xxx { - variable res \ - [info frame 0];# line 1457 - } - return [reduce $xxx::res] -} {type source line 1457 file info.test cmd {info frame 0} level 0} - -test info-30.3 {bs+nl in literal words, namespace multi-word script} { - namespace eval xxx variable res \ - [list [reduce [info frame 0]]];# line 1464 - return $xxx::res -} {type source line 1464 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.4 {bs+nl in literal words, eval script} -cleanup {unset res} -body { - eval { - set ::res \ - [reduce [info frame 0]];# line 1471 - } - return $res -} -result {type source line 1471 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.5 {bs+nl in literal words, eval script, with nested words} -body { - eval { - if {1} \ - { - set ::res \ - [reduce [info frame 0]];# line 1481 - } - } - return $res -} -cleanup {unset res} -result {type source line 1481 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.6 {bs+nl in computed word} -cleanup {unset res} -body { - set res "\ -[reduce [info frame 0]]";# line 1489 -} -result { type source line 1489 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.7 {bs+nl in computed word, in proc} -body { - proc abra {} { - return "\ -[reduce [info frame 0]]";# line 1495 - } - abra -} -cleanup { - rename abra {} -} -result { type source line 1495 file info.test cmd {info frame 0} proc ::abra level 0} - -test info-30.8 {bs+nl in computed word, nested eval} -body { - eval { - set \ - res "\ -[reduce [info frame 0]]";# line 1506 -} -} -cleanup {unset res} -result { type source line 1506 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.9 {bs+nl in computed word, nested eval} -body { - eval { - set \ - res "\ -[reduce \ - [info frame 0]]";# line 1515 -} -} -cleanup {unset res} -result { type source line 1515 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.10 {bs+nl in computed word, key to array} -body { - set tmp([set \ - res "\ -[reduce \ - [info frame 0]]"]) x ; #1523 - unset tmp - set res -} -cleanup {unset res} -result { type source line 1523 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.11 {bs+nl in subst arguments} -body { - subst {[set \ - res "\ -[reduce \ - [info frame 0]]"]} ; #1532 -} -cleanup {unset res} -result { type source line 1532 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.12 {bs+nl in computed word, nested eval} -body { - eval { - set \ - res "\ -[set x {}] \ -[reduce \ - [info frame 0]]";# line 1541 -} -} -cleanup {unset res x} -result { type source line 1541 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.13 {bs+nl in literal words, uplevel script, with nested words} -body { - subinterp ; set res [interp eval sub { uplevel #0 { - if {1} \ - { - set ::res \ - [reduce [info frame 0]];# line 1550 - } - } - set res }] ; interp delete sub ; set res -} -cleanup {unset res} -result {type source line 1550 file info.test cmd {info frame 0} level 0} - -test info-30.14 {bs+nl, literal word, uplevel through proc} { - subinterp ; set res [interp eval sub { proc abra {script} { - uplevel 1 $script - } - set res [abra { - return "\ -[reduce [info frame 0]]";# line 1562 - }] - rename abra {} - set res }] ; interp delete sub ; set res -} { type source line 1562 file info.test cmd {info frame 0} proc ::abra} - -test info-30.15 {bs+nl in literal words, nested proc body, compiled} { - proc a {} { - proc b {} { - if {1} \ - { - return \ - [reduce [info frame 0]];# line 1574 - } - } - } - a ; set res [b] - rename a {} - rename b {} - set res -} {type source line 1574 file info.test cmd {info frame 0} proc ::b level 0} - -test info-30.16 {bs+nl in multi-body switch, compiled} { - proc a {value} { - switch -regexp -- $value \ - ^key { info frame 0; # 1587 } \ - \t### { info frame 0; # 1588 } \ - {[0-9]*} { info frame 0; # 1589 } - } - set res {} - lappend res [reduce [a {key }]] - lappend res [reduce [a {1alpha}]] - set res "\n[join $res \n]" -} { -type source line 1587 file info.test cmd {info frame 0} proc ::a level 0 -type source line 1589 file info.test cmd {info frame 0} proc ::a level 0} - -test info-30.17 {bs+nl in multi-body switch, direct} { - switch -regexp -- {key } \ - ^key { reduce [info frame 0] ;# 1601 } \ - \t### { } \ - {[0-9]*} { } -} {type source line 1601 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.18 {bs+nl, literal word, uplevel through proc, appended, loss of primary tracking data} { - proc abra {script} { - append script "\n# end of script" - uplevel 1 $script - } - set res [abra { - return "\ -[reduce [info frame 0]]";# line 1613, still line of 3 appended script - }] - rename abra {} - set res -} { type eval line 3 cmd {info frame 0} proc ::abra} -# { type source line 1606 file info.test cmd {info frame 0} proc ::abra} - -test info-30.19 {bs+nl in single-body switch, compiled} { - proc a {value} { - switch -regexp -- $value { - ^key { reduce \ - [info frame 0] } - \t { reduce \ - [info frame 0] } - {[0-9]*} { reduce \ - [info frame 0] } - } - } - set res {} - lappend res [a {key }] - lappend res [a {1alpha}] - set res "\n[join $res \n]" -} { -type source line 1624 file info.test cmd {info frame 0} proc ::a level 0 -type source line 1628 file info.test cmd {info frame 0} proc ::a level 0} - -test info-30.20 {bs+nl in single-body switch, direct} { - switch -regexp -- {key } { \ - - ^key { reduce \ - [info frame 0] } - \t### { } - {[0-9]*} { } - } -} {type source line 1643 file info.test cmd {info frame 0} proc ::tcltest::RunTest} - -test info-30.21 {bs+nl in if, full compiled} { - proc a {value} { - if {$value} \ - {info frame 0} \ - {info frame 0} ; # 1653 - } - set res {} - lappend res [reduce [a 1]] - lappend res [reduce [a 0]] - set res "\n[join $res \n]" -} { -type source line 1652 file info.test cmd {info frame 0} proc ::a level 0 -type source line 1653 file info.test cmd {info frame 0} proc ::a level 0} - -test info-30.22 {bs+nl in computed word, key to array, compiled} { - proc a {} { - set tmp([set \ - res "\ -[reduce \ - [info frame 0]]"]) x ; #1668 - unset tmp - set res - } - set res [a] - rename a {} - set res -} { type source line 1668 file info.test cmd {info frame 0} proc ::a level 0} - -test info-30.23 {bs+nl in multi-body switch, full compiled} { - proc a {value} { - switch -exact -- $value \ - key { info frame 0; # 1680 } \ - xxx { info frame 0; # 1681 } \ - 000 { info frame 0; # 1682 } - } - set res {} - lappend res [reduce [a key]] - lappend res [reduce [a 000]] - set res "\n[join $res \n]" -} { -type source line 1680 file info.test cmd {info frame 0} proc ::a level 0 -type source line 1682 file info.test cmd {info frame 0} proc ::a level 0} - -test info-30.24 {bs+nl in single-body switch, full compiled} { - proc a {value} { - switch -exact -- $value { - key { reduce \ - [info frame 0] } - xxx { reduce \ - [info frame 0] } - 000 { reduce \ - [info frame 0] } - } - } - set res {} - lappend res [a key] - lappend res [a 000] - set res "\n[join $res \n]" -} { -type source line 1696 file info.test cmd {info frame 0} proc ::a level 0 -type source line 1700 file info.test cmd {info frame 0} proc ::a level 0} - -test info-30.25 {TIP 280 for compiled [subst]} { - subst {[reduce [info frame 0]]} ; # 1712 -} {type source line 1712 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.26 {TIP 280 for compiled [subst]} { - subst \ - {[reduce [info frame 0]]} ; # 1716 -} {type source line 1716 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.27 {TIP 280 for compiled [subst]} { - subst { -[reduce [info frame 0]]} ; # 1720 -} { -type source line 1720 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.28 {TIP 280 for compiled [subst]} { - subst {\ -[reduce [info frame 0]]} ; # 1725 -} { type source line 1725 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.29 {TIP 280 for compiled [subst]} { - subst {foo\ -[reduce [info frame 0]]} ; # 1729 -} {foo type source line 1729 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.30 {TIP 280 for compiled [subst]} { - subst {foo -[reduce [info frame 0]]} ; # 1733 -} {foo -type source line 1733 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.31 {TIP 280 for compiled [subst]} { - subst {[][reduce [info frame 0]]} ; # 1737 -} {type source line 1737 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.32 {TIP 280 for compiled [subst]} { - subst {[\ -][reduce [info frame 0]]} ; # 1741 -} {type source line 1741 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.33 {TIP 280 for compiled [subst]} { - subst {[ -][reduce [info frame 0]]} ; # 1745 -} {type source line 1745 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.34 {TIP 280 for compiled [subst]} { - subst {[format %s {} -][reduce [info frame 0]]} ; # 1749 -} {type source line 1749 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.35 {TIP 280 for compiled [subst]} { - subst {[format %s {} -] -[reduce [info frame 0]]} ; # 1754 -} { -type source line 1754 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.36 {TIP 280 for compiled [subst]} { - subst { -[format %s {}][reduce [info frame 0]]} ; # 1759 -} { -type source line 1759 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.37 {TIP 280 for compiled [subst]} { - subst { -[format %s {}] -[reduce [info frame 0]]} ; # 1765 -} { - -type source line 1765 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.38 {TIP 280 for compiled [subst]} { - subst {\ -[format %s {}][reduce [info frame 0]]} ; # 1771 -} { type source line 1771 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.39 {TIP 280 for compiled [subst]} { - subst {\ -[format %s {}]\ -[reduce [info frame 0]]} ; # 1776 -} { type source line 1776 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.40 {TIP 280 for compiled [subst]} -setup { - unset -nocomplain empty -} -body { - set empty {} - subst {$empty[reduce [info frame 0]]} ; # 1782 -} -cleanup { - unset empty -} -result {type source line 1782 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.41 {TIP 280 for compiled [subst]} -setup { - unset -nocomplain empty -} -body { - set empty {} - subst {$empty -[reduce [info frame 0]]} ; # 1791 -} -cleanup { - unset empty -} -result { -type source line 1791 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.42 {TIP 280 for compiled [subst]} -setup { - unset -nocomplain empty -} -body { - set empty {}; subst {$empty\ -[reduce [info frame 0]]} ; # 1800 -} -cleanup { - unset empty -} -result { type source line 1800 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.43 {TIP 280 for compiled [subst]} -body { - unset -nocomplain a\nb - set a\nb {} - subst {${a -b}[reduce [info frame 0]]} ; # 1808 -} -cleanup {unset a\nb} -result {type source line 1808 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.44 {TIP 280 for compiled [subst]} { - unset -nocomplain a - set a(\n) {} - subst {$a( -)[reduce [info frame 0]]} ; # 1814 -} {type source line 1814 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.45 {TIP 280 for compiled [subst]} { - unset -nocomplain a - set a() {} - subst {$a([ -return -level 0])[reduce [info frame 0]]} ; # 1820 -} {type source line 1820 file info.test cmd {info frame 0} proc ::tcltest::RunTest} -test info-30.46 {TIP 280 for compiled [subst]} { - unset -nocomplain a - set a(1825) YES; set a(1824) 1824; set a(1826) 1826 - subst {$a([dict get [info frame 0] line])} ; # 1825 -} YES -test info-30.47 {TIP 280 for compiled [subst]} { - unset -nocomplain a - set a(\n1831) YES; set a(\n1830) 1830; set a(\n1832) 1832 - subst {$a( -[dict get [info frame 0] line])} ; # 1831 -} YES -unset -nocomplain a - -test info-30.48 {Bug 2850901} testevalex { - testevalex {return -level 0 [format %s {} -][reduce [info frame 0]]} ; # line 2 of the eval -} {type eval line 2 cmd {info frame 0} proc ::tcltest::RunTest} - - -# ------------------------------------------------------------------------- -# literal sharing 2, bug 2933089 - -test info-39.1 {location information not confused by literal sharing, bug 2933089} -setup { - set result {} - - proc print_one {} {} - proc test_info_frame {} { - set x 1 - set y x - - if "$x != 1" { - } else { - print_one - } ;#line 1854^ - - if "$$y != 1" { - } else { - print_one - } ;#line 1859^ - # Do not put the comments listing the line numbers into the - # branches. We need shared literals, and the comments would - # make them different, thus unshared. - } - - proc get_frame_info { cmd_str op } { - lappend ::result [reduce [eval {info frame -3}]] - } - trace add execution print_one enter get_frame_info -} -body { - test_info_frame; - join $result \n -} -cleanup { - trace remove execution print_one enter get_frame_info - rename get_frame_info {} - rename test_info_frame {} - rename print_one {} -} -result {type source line 1854 file info.test cmd print_one proc ::test_info_frame level 1 -type source line 1859 file info.test cmd print_one proc ::test_info_frame level 1} - -# ------------------------------------------------------------------------- -# Tests moved to the end to not disturb other tests and their locations. - -test info-38.6 {location information for uplevel, ppl, proc-proc-literal} -match glob -setup {subinterp} -body { - interp eval sub { - proc etrace {} { - set res {} - set level [info frame] - while {$level} { - lappend res [list $level [reduce [info frame $level]]] - incr level -1 - } - return $res - } - proc control {vv script} { - upvar 1 $vv var - return [uplevel 1 $script] - } - proc datal {} { - control y { - set y PPL - etrace - } - } - join [lrange [datal] 0 4] \n - } -} -result {* {type source line 1890 file info.test cmd {info frame $level} proc ::etrace level 0} -* {type source line 1902 file info.test cmd etrace proc ::control} -* {type source line 1897 file info.test cmd {uplevel 1 $script} proc ::control} -* {type source line 1900 file info.test cmd control proc ::datal level 1} -* {type source line 1905 file info.test cmd datal level 2}} -cleanup {interp delete sub} - -test info-38.4 {location information for uplevel, dpv, direct-proc-literal} -match glob -setup {subinterp} -body { - interp eval sub { - proc etrace {} { - set res {} - set level [info frame] - while {$level} { - lappend res [list $level [reduce [info frame $level]]] - incr level -1 - } - return $res - } - proc control {vv script} { - upvar 1 $vv var - return [uplevel 1 $script] - } - join [lrange [control y { - set y DPL - etrace - }] 0 3] \n - } -} -result {* {type source line 1919 file info.test cmd {info frame $level} proc ::etrace level 0} -* {type source line 1930 file info.test cmd etrace proc ::control} -* {type source line 1926 file info.test cmd {uplevel 1 $script} proc ::control} -* {type source line 1928 file info.test cmd control level 1}} -cleanup {interp delete sub} - -test info-38.2 {location information for uplevel, dl, direct-literal} -match glob -setup {subinterp} -body { - interp eval sub { - proc etrace {} { - set res {} - set level [info frame] - while {$level} { - lappend res [list $level [reduce [info frame $level]]] - incr level -1 - } - return $res - } - join [lrange [uplevel \#0 { - set y DL. - etrace - }] 0 2] \n - } -} -result {* {type source line 1944 file info.test cmd {info frame $level} proc ::etrace level 0} -* {type source line 1951 file info.test cmd etrace level 1} -* {type source line 1949 file info.test cmd uplevel\\ \\\\ level 1}} -cleanup {interp delete sub} - -# This test at the end of this file _only_ to avoid disturbing above line -# numbers. It _belongs_ after info-9.12 -test info-9.13 {info level option, value in global context} -body { - uplevel #0 {info level 2} -} -returnCodes error -result {bad level "2"} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - catch {*}{ - {info frame 0} - res - } - return $res -} -test info-33.4 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 1968 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - dict for {a b} {c d} {*}{ - {set res [info frame 0]} - } - return $res -} -test info-33.5 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 1983 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - set d {a b} - dict update d x y {*}{ - {set res [info frame 0]} - } - return $res -} -test info-33.6 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 1998 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - set d {} - dict with d {*}{ - {set res [info frame 0]} - } - return $res -} -test info-33.7 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2013 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - for {*}{ - {set res [info frame 0]} - {1} {} {break} - } - return $res -} -test info-33.8 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2027 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - for {*}{ - {} {1} {} - {set res [info frame 0]; break} - } - return $res -} -test info-33.9 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2043 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - for {*}{ - {} {1} - {return [info frame 0]} - {} - } -} -test info-33.10 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2058 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - for {*}{ - {} - {[return [info frame 0]]} - {} {} - } -} -test info-33.11 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2073 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - foreach {*}{ - x - } [return [info frame 0]] {} -} -test info-33.12 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2088 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - foreach {*}{ - x y - {set res [info frame 0]} - } - return $res -} -test info-33.13 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2101 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - if {*}{ - {[return [info frame 0]]} - {} - } -} -test info-33.14 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2115 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - if 0 {*}{ - {} else - {return [info frame 0]} - } -} -test info-33.15 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2130 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - incr {*}{ - x - } [return [info frame 0]] -} -test info-33.16 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2144 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - info level {*}{ - } [return [info frame 0]] -} -test info-33.17 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2156 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - string match {*}{ - } [return [info frame 0]] {} -} -test info-33.18 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2168 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - string match {*}{ - {} - } [return [info frame 0]] -} -test info-33.19 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2181 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - string length {*}{ - } [return [info frame 0]] -} -test info-33.20 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2193 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - while {*}{ - {[return [info frame 0]]} - } {} -} -test info-33.21 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2205 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - switch -- {*}{ - } [return [info frame 0]] {*}{ - } x y -} -test info-33.22 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2218 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - try {*}{ - {set res [info frame 0]} - } - return $res -} -test info-33.23 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2231 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - try {*}{ - {set res [info frame 0]} - } finally {} - return $res -} -test info-33.24 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2245 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - try {*}{ - {set res [info frame 0]} - } on ok {} {} - return $res -} -test info-33.25 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2259 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - try {*}{ - {set res [info frame 0]} - } on ok {} {} finally {} - return $res -} -test info-33.26 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2273 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - while 1 {*}{ - {return [info frame 0]} - } -} -test info-33.27 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2287 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - try {} finally {*}{ - {return [info frame 0]} - } -} -test info-33.28 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2300 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - try {} on ok {} {} finally {*}{ - {return [info frame 0]} - } -} -test info-33.29 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2313 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - try {} on ok {} {*}{ - {return [info frame 0]} - } -} -test info-33.30 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2326 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - try {} on ok {} {*}{ - {return [info frame 0]} - } finally {} -} -test info-33.31 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2339 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - binary format {*}{ - } [return [info frame 0]] -} -test info-33.32 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2352 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - set format format - binary $format {*}{ - } [return [info frame 0]] -} -test info-33.33 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2365 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - append x {*}{ - } [return [info frame 0]] -} -test info-33.34 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2377 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -namespace eval foo {} -proc foo::bar {} { - append {*}{ - } x([return [info frame 0]]) {*}{ - } a -} -test info-33.35 {{*}, literal, simple, bytecompiled} -body { - reduce [foo::bar] -} -cleanup { - namespace delete foo -} -result {type source line 2389 file info.test cmd {info frame 0} proc ::foo::bar level 0} - -# ------------------------------------------------------------------------- -unset -nocomplain res # cleanup catch {namespace delete test_ns_info1 test_ns_info2} ::tcltest::cleanupTests return + diff --git a/tests/nre.test b/tests/nre.test index e512eac..a829b7f 100644 --- a/tests/nre.test +++ b/tests/nre.test @@ -28,8 +28,8 @@ if {[testConstraint testnrelevels]} { namespace eval testnre { namespace path ::tcl::mathop # - # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels, - # cmdFrame level, callFrame level, tosPtr and callback depth + # [testnrelevels] returns a 5-list with: C-stack depth, iPtr->numlevels, + # callFrame level, tosPtr and callback depth # variable last [testnrelevels] proc depthDiff {} { @@ -52,7 +52,7 @@ if {[testConstraint testnrelevels]} { namespace upvar [namespace qualifiers \ [namespace origin depthDiff]] abs abs incr abs [lindex [testnrelevels] 0] - return [list [lrange $x 0 3] $abs] + return [list [lrange $x 0 2] $abs] } } proc makebody txt { @@ -73,7 +73,7 @@ test nre-1.1 {self-recursive procs} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 1 1 1} 0} +} -result {{0 1 1} 0} test nre-1.2 {self-recursive lambdas} -setup { set a [list i [makebody {apply $::a $i}]] } -body { @@ -83,7 +83,7 @@ test nre-1.2 {self-recursive lambdas} -setup { unset a } -constraints { testnrelevels -} -result {{0 1 1 1} 0} +} -result {{0 1 1} 0} test nre-1.3 {mutually recursive procs and lambdas} -setup { proc a i { apply $::b [incr i] @@ -97,7 +97,7 @@ test nre-1.3 {mutually recursive procs and lambdas} -setup { unset b } -constraints { testnrelevels -} -result {{0 2 2 2} 0} +} -result {{0 2 2} 0} # # Test that aliases are non-recursive @@ -114,7 +114,7 @@ test nre-2.1 {alias is not recursive} -setup { rename b {} } -constraints { testnrelevels -} -result {{0 2 1 1} 0} +} -result {{0 2 1} 0} # # Test that imports are non-recursive @@ -134,7 +134,7 @@ test nre-3.1 {imports are not recursive} -setup { namespace delete ::foo } -constraints { testnrelevels -} -result {{0 2 1 1} 0} +} -result {{0 2 1} 0} test nre-4.1 {ensembles are not recursive} -setup { proc a i [makebody {b foo $i}] @@ -149,7 +149,7 @@ test nre-4.1 {ensembles are not recursive} -setup { rename b {} } -constraints { testnrelevels -} -result {{0 2 1 1} 0} +} -result {{0 2 1} 0} test nre-4.2 {(compiled) ensembles do not break tailcall} -setup { # Fix Bug d87cb18205 @@ -183,7 +183,7 @@ test nre-5.1 {[namespace eval] is not recursive} -setup { namespace delete ::foo } -constraints { testnrelevels -} -result {{0 2 2 2} 0} +} -result {{0 2 2} 0} test nre-5.2 {[namespace eval] is not recursive} -setup { namespace eval ::foo { setabs @@ -195,7 +195,7 @@ test nre-5.2 {[namespace eval] is not recursive} -setup { namespace delete ::foo } -constraints { testnrelevels -} -result {{0 2 2 2} 0} +} -result {{0 2 2} 0} test nre-6.1 {[uplevel] is not recursive} -setup { proc a i [makebody {uplevel 1 [list a $i]}] @@ -206,7 +206,7 @@ test nre-6.1 {[uplevel] is not recursive} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 2 2 0} 0} +} -result {{0 2 0} 0} test nre-6.2 {[uplevel] is not recursive} -setup { setabs proc a i [makebody {uplevel 1 "set x $i; a $i"}] @@ -216,7 +216,7 @@ test nre-6.2 {[uplevel] is not recursive} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 2 2 0} 0} +} -result {{0 2 0} 0} test nre-7.1 {[catch] is not recursive} -setup { setabs @@ -227,7 +227,7 @@ test nre-7.1 {[catch] is not recursive} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 3 3 0} 0} +} -result {{0 3 0} 0} test nre-7.2 {[if] is not recursive} -setup { setabs proc a i [makebody {uplevel 1 "if 1 {a $i}"}] @@ -237,7 +237,7 @@ test nre-7.2 {[if] is not recursive} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 2 2 0} 0} +} -result {{0 2 0} 0} test nre-7.3 {[while] is not recursive} -setup { setabs proc a i [makebody {uplevel 1 "while 1 {set res \[a $i\]; break}; set res"}] @@ -247,7 +247,7 @@ test nre-7.3 {[while] is not recursive} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 2 2 0} 0} +} -result {{0 2 0} 0} test nre-7.4 {[for] is not recursive} -setup { setabs proc a i [makebody {uplevel 1 "for {set j 0} {\$j < 10} {incr j} {set res \[a $i\]; break}; set res"}] @@ -257,7 +257,7 @@ test nre-7.4 {[for] is not recursive} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 2 2 0} 0} +} -result {{0 2 0} 0} test nre-7.5 {[foreach] is not recursive} -setup { # # Enable once [foreach] is NR-enabled @@ -270,7 +270,7 @@ test nre-7.5 {[foreach] is not recursive} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 3 3 0} 0} +} -result {{0 3 0} 0} test nre-7.6 {[eval] is not recursive} -setup { proc a i [makebody {eval [list a $i]}] } -body { @@ -280,7 +280,7 @@ test nre-7.6 {[eval] is not recursive} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 2 2 1} 0} +} -result {{0 2 1} 0} test nre-7.7 {[eval] is not recursive} -setup { proc a i [makebody {eval "a $i"}] } -body { @@ -290,7 +290,7 @@ test nre-7.7 {[eval] is not recursive} -setup { rename a {} } -constraints { testnrelevels -} -result {{0 2 2 1} 0} +} -result {{0 2 1} 0} test nre-7.8 {bug #2910748: switch out of stale BC is not nre-aware} -setup { proc foo args {} foo @@ -354,7 +354,7 @@ test nre-oo.1 {really deep calls in oo - direct} -setup { foo destroy } -constraints { testnrelevels -} -result {{0 1 1 1} 0} +} -result {{0 1 1} 0} test nre-oo.2 {really deep calls in oo - call via [self]} -setup { oo::object create foo oo::objdefine foo method bar i [makebody {[self] bar $i}] @@ -365,7 +365,7 @@ test nre-oo.2 {really deep calls in oo - call via [self]} -setup { foo destroy } -constraints { testnrelevels -} -result {{0 1 1 1} 0} +} -result {{0 1 1} 0} test nre-oo.3 {really deep calls in oo - private calls} -setup { oo::object create foo oo::objdefine foo method bar i [makebody {my bar $i}] @@ -376,7 +376,7 @@ test nre-oo.3 {really deep calls in oo - private calls} -setup { foo destroy } -constraints { testnrelevels -} -result {{0 1 1 1} 0} +} -result {{0 1 1} 0} test nre-oo.4 {really deep calls in oo - overriding} -setup { oo::class create foo { method bar i [makebody {my bar $i}] @@ -392,7 +392,7 @@ test nre-oo.4 {really deep calls in oo - overriding} -setup { foo destroy } -constraints { testnrelevels -} -result {{0 1 1 1} 0} +} -result {{0 1 1} 0} test nre-oo.5 {really deep calls in oo - forwards} -setup { oo::object create foo set body [makebody {my boo $i}] @@ -407,7 +407,7 @@ test nre-oo.5 {really deep calls in oo - forwards} -setup { foo destroy } -constraints { testnrelevels -} -result {{0 2 1 1} 0} +} -result {{0 2 1} 0} # # NASTY BUG found by tcllib's interp package diff --git a/tests/oo.test b/tests/oo.test index 2112f10..332395d 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -2847,45 +2847,45 @@ test oo-21.4 {OO: inheritance ordering} -setup { A destroy } -result {Emix-filt B-filt D-cfilt B-cfilt Fmix Emix o D B C A} -test oo-22.1 {OO and info frame} -setup { - oo::class create c - c create i -} -match glob -body { - oo::define c self method frame {} { - info frame 0 - } - oo::define c { - method frames {} { - info frame 0 - } - method level {} { - info frame - } - } - oo::objdefine i { - method frames {} { - list [next] [info frame 0] - } - method level {} { - expr {[next] - [info frame]} - } - } - list [i level] [i frames] [dict get [c frame] object] -} -cleanup { - c destroy -} -result {1 {{* cmd {info frame 0} method frames class ::c level 0} {* cmd {info frame 0} method frames object ::i level 0}} ::c} -test oo-22.2 {OO and info frame: Bug 3001438} -setup { - oo::class create c -} -body { - oo::define c method test {{x 1}} { - if {$x} {my test 0} - lsort {q w e r t y u i o p}; # Overwrite the Tcl stack - info frame 0 - } - [c new] test -} -match glob -cleanup { - c destroy -} -result {* cmd {info frame 0} method test class ::c level 0} +#test oo-22.1 {OO and info frame} -setup { +# oo::class create c +# c create i +#} -match glob -body { +# oo::define c self method frame {} { +# info frame 0 +# } +# oo::define c { +# method frames {} { +# info frame 0 +# } +# method level {} { +# info frame +# } +# } +# oo::objdefine i { +# method frames {} { +# list [next] [info frame 0] +# } +# method level {} { +# expr {[next] - [info frame]} +# } +# } +# list [i level] [i frames] [dict get [c frame] object] +#} -cleanup { +# c destroy +#} -result {1 {{* cmd {info frame 0} method frames class ::c level 0} {* cmd {info frame 0} method frames object ::i level 0}} ::c} +#test oo-22.2 {OO and info frame: Bug 3001438} -setup { +# oo::class create c +#} -body { +# oo::define c method test {{x 1}} { +# if {$x} {my test 0} +# lsort {q w e r t y u i o p}; # Overwrite the Tcl stack +# info frame 0 +# } +# [c new] test +#} -match glob -cleanup { +# c destroy +#} -result {* cmd {info frame 0} method test class ::c level 0} # Prove that the issue in [Bug 1865054] isn't an issue any more test oo-23.1 {Self-like derivation; complex case!} -setup { diff --git a/tests/parse.test b/tests/parse.test index d73c725..2bdc817 100644 --- a/tests/parse.test +++ b/tests/parse.test @@ -453,7 +453,7 @@ test parse-9.1 {Tcl_LogCommandInfo, line numbers} testevalex { } {1 {can't read "x": no such variable while executing "set x" - ("for" body line 5) + (loop body line 5) invoked from within "for {} 1 {} { @@ -1124,12 +1124,12 @@ test parse-21.0 {Bug 1884496} testevent { testevent queue a head $::script vwait done } {} -test parse-21.1 {TCL_EVAL_DIRECT coverage} testevent { - testevent queue a head {testevent delete a; \ - set ::done [dict get [info frame 0] line]} - vwait done - set ::done -} 2 +#test parse-21.1 {TCL_EVAL_DIRECT coverage} testevent { +# testevent queue a head {testevent delete a; \ +# set ::done [dict get [info frame 0] line]} +# vwait done +# set ::done +#} 2 cleanupTests } diff --git a/tests/result.test b/tests/result.test index 9e8a66b..d95535b 100644 --- a/tests/result.test +++ b/tests/result.test @@ -134,14 +134,15 @@ test result-6.3 {Bug 2383005} { catch {return -code error -errorcode {{}a} eek} m set m } {bad -errorcode value: expected a list but got "{}a"} -test result-6.4 {non-list -errorstack} -body { - catch {return -code error -errorstack {{}a} eek} m o - list $m [dict get $o -errorcode] [dict get $o -errorstack] -} -match glob -result {{bad -errorstack value: expected a list but got "{}a"} {TCL RESULT NONLIST_ERRORSTACK} {INNER * UP 1}} -test result-6.5 {odd-sized-list -errorstack} -body { - catch {return -code error -errorstack a eek} m o - list $m [dict get $o -errorcode] [dict get $o -errorstack] -} -match glob -result {{forbidden odd-sized list for -errorstack: "a"} {TCL RESULT ODDSIZEDLIST_ERRORSTACK} {INNER * UP 1}} +#test result-6.4 {non-list -errorstack} -body { +# catch {return -code error -errorstack {{}a} eek} m o +# list $m [dict get $o -errorcode] [dict get $o -errorstack] +#} -match glob -result {{bad -errorstack value: expected a list but got "{}a"} {TCL RESULT NONLIST_ERRORSTACK} {INNER * UP 1}} +#test result-6.5 {odd-sized-list -errorstack} -body { +# catch {return -code error -errorstack a eek} m o +# list $m [dict get $o -errorcode] [dict get $o -errorstack] +#} -match glob -result {{forbidden odd-sized list for -errorstack: "a"} {TCL RESULT ODDSIZEDLIST_ERRORSTACK} {INNER * UP 1}} + # cleanup cleanupTests return diff --git a/tests/source.test b/tests/source.test index 0235bd1..a92ba03 100644 --- a/tests/source.test +++ b/tests/source.test @@ -187,15 +187,15 @@ test source-3.5 {return with special code etc.} -setup { invoked from within "source $sourcefile"} {a b c}} -test source-4.1 {continuation line parsing} -setup { - set sourcefile [makeFile [string map {CL \\\n} { - format %s "[dict get [info frame 0] type]:CL[dict get [info frame 0] line]CL[dict get [info frame 0] line]CL[dict get [info frame 0] line]" - }] source.file] -} -body { - source $sourcefile -} -cleanup { - removeFile source.file -} -result {source: 3 4 5} +#test source-4.1 {continuation line parsing} -setup { +# set sourcefile [makeFile [string map {CL \\\n} { +# format %s "[dict get [info frame 0] type]:CL[dict get [info frame 0] line]CL[dict get [info frame 0] line]CL[dict get [info frame 0] line]" +# }] source.file] +#} -body { +# source $sourcefile +#} -cleanup { +# removeFile source.file +#} -result {source: 3 4 5} test source-6.1 {source is binary ok} -setup { # Note [makeFile] writes in the system encoding. diff --git a/tests/tailcall.test b/tests/tailcall.test index 26f3cbf..e075fac 100644 --- a/tests/tailcall.test +++ b/tests/tailcall.test @@ -27,8 +27,8 @@ testConstraint testnrelevels [llength [info commands testnrelevels]] if {[testConstraint testnrelevels]} { namespace eval testnre { # - # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels, - # cmdFrame level, callFrame level, tosPtr and callback depth + # [testnrelevels] returns a 5-list with: C-stack depth, iPtr->numlevels, + # callFrame level, tosPtr and callback depth # variable last [testnrelevels] proc depthDiff {} { @@ -69,7 +69,7 @@ test tailcall-0.1 {tailcall is constant space} -constraints testnrelevels -setup a 0 } -cleanup { rename a {} -} -result {0 0 0 0 0 0} +} -result {0 0 0 0 0} test tailcall-0.2 {tailcall is constant space} -constraints testnrelevels -setup { set a { i { @@ -86,7 +86,7 @@ test tailcall-0.2 {tailcall is constant space} -constraints testnrelevels -setup apply $a 0 } -cleanup { unset a -} -result {0 0 0 0 0 0} +} -result {0 0 0 0 0} test tailcall-0.3 {tailcall is constant space} -constraints testnrelevels -setup { proc a i { @@ -104,7 +104,7 @@ test tailcall-0.3 {tailcall is constant space} -constraints testnrelevels -setup } -cleanup { rename a {} rename b {} -} -result {0 0 0 0 0 0} +} -result {0 0 0 0 0} test tailcall-0.4 {tailcall is constant space} -constraints testnrelevels -setup { namespace eval ::ns { @@ -127,7 +127,7 @@ test tailcall-0.4 {tailcall is constant space} -constraints testnrelevels -setup } -cleanup { rename b {} namespace delete ::ns -} -result {0 0 0 0 0 0} +} -result {0 0 0 0 0} test tailcall-0.5 {tailcall is constant space} -constraints testnrelevels -setup { proc b i { @@ -145,7 +145,7 @@ test tailcall-0.5 {tailcall is constant space} -constraints testnrelevels -setup } -cleanup { rename a {} rename b {} -} -result {0 0 0 0 0 0} +} -result {0 0 0 0 0} test tailcall-0.5.1 {tailcall is constant space} -constraints testnrelevels -setup { # @@ -175,7 +175,7 @@ test tailcall-0.5.1 {tailcall is constant space} -constraints testnrelevels -set rename b {} namespace ensemble configure dict -map $map0 unset map map0 -} -result {0 0 0 0 0 0} +} -result {0 0 0 0 0} test tailcall-0.6 {tailcall is constant space} -constraints {testnrelevels knownBug} -setup { # @@ -200,7 +200,7 @@ test tailcall-0.6 {tailcall is constant space} -constraints {testnrelevels known rename a {} rename c {} rename d {} -} -result {0 0 0 0 0 0} +} -result {0 0 0 0 0} test tailcall-0.7 {tailcall is constant space} -constraints testnrelevels -setup { catch {rename foo {}} @@ -221,7 +221,7 @@ test tailcall-0.7 {tailcall is constant space} -constraints testnrelevels -setup } -cleanup { rename a {} rename foo {} -} -result {0 0 0 0 0 0} +} -result {0 0 0 0 0} test tailcall-1 {tailcall} -body { namespace eval a { diff --git a/tests/upvar.test b/tests/upvar.test index 5ea870d..e83b6fd 100644 --- a/tests/upvar.test +++ b/tests/upvar.test @@ -414,16 +414,16 @@ test upvar-9.7 {Tcl_UpVar procedure} testupvar { } {1234} catch {unset a} -test upvar-10.1 {CompileWord OBOE} -setup { - proc linenumber {} {dict get [info frame -1] line} -} -body { - apply {n { - upvar 1 {*}{ - } [return [incr n -[linenumber]]] x - }} [linenumber] -} -cleanup { - rename linenumber {} -} -result 1 +#test upvar-10.1 {CompileWord OBOE} -setup { +# proc linenumber {} {dict get [info frame -1] line} +#} -body { +# apply {n { +# upvar 1 {*}{ +# } [return [incr n -[linenumber]]] x +# }} [linenumber] +#} -cleanup { +# rename linenumber {} +#} -result 1 # # Tests for 'namespace upvar'. As the implementation is essentially the same as @@ -548,36 +548,36 @@ test upvar-NS-2.2 {TIP 323} -setup { namespace delete test_ns_1 } -result {} -test upvar-NS-3.1 {CompileWord OBOE} -setup { - proc linenumber {} {dict get [info frame -1] line} -} -body { - apply {n { - namespace upvar {*}{ - } [return [incr n -[linenumber]]] x y - }} [linenumber] -} -cleanup { - rename linenumber {} -} -result 1 -test upvar-NS-3.2 {CompileWord OBOE} -setup { - proc linenumber {} {dict get [info frame -1] line} -} -body { - apply {n { - namespace upvar :: {*}{ - } [return [incr n -[linenumber]]] x - }} [linenumber] -} -cleanup { - rename linenumber {} -} -result 1 -test upvar-NS-3.3 {CompileWord OBOE} -setup { - proc linenumber {} {dict get [info frame -1] line} -} -body { - apply {n { - variable x {*}{ - } [return [incr n -[linenumber]]] - }} [linenumber] -} -cleanup { - rename linenumber {} -} -result 1 +#test upvar-NS-3.1 {CompileWord OBOE} -setup { +# proc linenumber {} {dict get [info frame -1] line} +#} -body { +# apply {n { +# namespace upvar {*}{ +# } [return [incr n -[linenumber]]] x y +# }} [linenumber] +#} -cleanup { +# rename linenumber {} +#} -result 1 +#test upvar-NS-3.2 {CompileWord OBOE} -setup { +# proc linenumber {} {dict get [info frame -1] line} +#} -body { +# apply {n { +# namespace upvar :: {*}{ +# } [return [incr n -[linenumber]]] x +# }} [linenumber] +#} -cleanup { +# rename linenumber {} +#} -result 1 +#test upvar-NS-3.3 {CompileWord OBOE} -setup { +# proc linenumber {} {dict get [info frame -1] line} +#} -body { +# apply {n { +# variable x {*}{ +# } [return [incr n -[linenumber]]] +# }} [linenumber] +#} -cleanup { +# rename linenumber {} +#} -result 1 # cleanup ::tcltest::cleanupTests diff --git a/tests/var.test b/tests/var.test index 0531746..8934b01 100644 --- a/tests/var.test +++ b/tests/var.test @@ -883,17 +883,17 @@ test var-20.10 {[bc1a96407a] array set don't compile bad varname} -body { apply {{} {set name foo(bar); array set $name {a 1}}} } -returnCodes error -match glob -result * -test var-21.0 {PushVarNameWord OBOE in compiled unset} -setup { - proc linenumber {} {dict get [info frame -1] line} -} -body { - apply {n { - set foo bar - unset foo {*}{ - } [return [incr n -[linenumber]]] - }} [linenumber] -} -cleanup { - rename linenumber {} -} -result 1 +#test var-21.0 {PushVarNameWord OBOE in compiled unset} -setup { +# proc linenumber {} {dict get [info frame -1] line} +#} -body { +# apply {n { +# set foo bar +# unset foo {*}{ +# } [return [incr n -[linenumber]]] +# }} [linenumber] +#} -cleanup { +# rename linenumber {} +#} -result 1 test var-22.0 {leak in array element unset: Bug a3309d01db} -setup { proc getbytes {} { diff --git a/tests/while.test b/tests/while.test index 642ec93..4beb52c 100644 --- a/tests/while.test +++ b/tests/while.test @@ -393,7 +393,7 @@ test while-4.9 {while (not compiled): error compiling command body} -body { } -result {wrong # args: should be "set varName ?newValue?" while *ing "set" - ("while" body line 1) + (loop body line 1) invoked from within "$z {$i < 5} {set}"} test while-4.10 {while (not compiled): simple command body} -body { |