diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-10-14 06:08:50 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-10-14 06:08:50 (GMT) |
| commit | cfc633e793bcf3f8419aac8b7084c13b2f8dbaa4 (patch) | |
| tree | 58b484a653058cac3bd24fba45dcc1578ac093c5 /generic/tclExecute.c | |
| parent | a09671a0a00f2d3e4abf4747a072da94b0320459 (diff) | |
| parent | f70e1f98b3e5235a48e0fbea21515ed7e277e6cd (diff) | |
| download | tcl-cfc633e793bcf3f8419aac8b7084c13b2f8dbaa4.zip tcl-cfc633e793bcf3f8419aac8b7084c13b2f8dbaa4.tar.gz tcl-cfc633e793bcf3f8419aac8b7084c13b2f8dbaa4.tar.bz2 | |
Merge 8.7
Diffstat (limited to 'generic/tclExecute.c')
| -rw-r--r-- | generic/tclExecute.c | 108 |
1 files changed, 75 insertions, 33 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index c80e12b..d1d7037 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -855,8 +855,8 @@ TclCreateExecEnv( * [sizeof(Tcl_Obj*)] */ { ExecEnv *eePtr = (ExecEnv *)ckalloc(sizeof(ExecEnv)); - ExecStack *esPtr = (ExecStack *)ckalloc(sizeof(ExecStack) - + (size_t) (size-1) * sizeof(Tcl_Obj *)); + ExecStack *esPtr = (ExecStack *)ckalloc(offsetof(ExecStack, stackWords) + + size * sizeof(Tcl_Obj *)); eePtr->execStackPtr = esPtr; TclNewIntObj(eePtr->constants[0], 0); @@ -1121,7 +1121,7 @@ GrowEvaluationStack( newElems = needed; #endif - newBytes = sizeof(ExecStack) + (newElems-1) * sizeof(Tcl_Obj *); + newBytes = offsetof(ExecStack, stackWords) + newElems * sizeof(Tcl_Obj *); oldPtr = esPtr; esPtr = (ExecStack *)ckalloc(newBytes); @@ -2130,6 +2130,22 @@ TEBCresume( if (!pc) { /* bytecode is starting from scratch */ pc = codePtr->codeStart; + + /* + * Reset the interp's result to avoid possible duplications of large + * objects [3c6e47363e], [781585], [804681], This can happen by start + * also in nested compiled blocks (enclosed in parent cycle). + * See else branch below for opposite handling by continuation/resume. + */ + + objPtr = iPtr->objResultPtr; + if (objPtr->refCount > 1) { + TclDecrRefCount(objPtr); + TclNewObj(objPtr); + Tcl_IncrRefCount(objPtr); + iPtr->objResultPtr = objPtr; + } + goto cleanup0; } else { /* resume from invocation */ @@ -2169,7 +2185,7 @@ TEBCresume( objc, cmdNameBuf), Tcl_GetObjResult(interp)); /* - * Reset the interp's result to avoid possible duplications of large + * Obtain and reset interp's result to avoid possible duplications of * objects [Bug 781585]. We do not call Tcl_ResetResult to avoid any * side effects caused by the resetting of errorInfo and errorCode * [Bug 804681], which are not needed here. We chose instead to @@ -3619,7 +3635,7 @@ TEBCresume( case INST_INCR_SCALAR_STK_IMM: case INST_INCR_STK_IMM: increment = TclGetInt1AtPtr(pc+1); - incrPtr = Tcl_NewIntObj(increment); + TclNewIntObj(incrPtr, increment); Tcl_IncrRefCount(incrPtr); pcAdjustment = 2; @@ -3654,7 +3670,7 @@ TEBCresume( case INST_INCR_ARRAY1_IMM: opnd = TclGetUInt1AtPtr(pc+1); increment = TclGetInt1AtPtr(pc+2); - incrPtr = Tcl_NewIntObj(increment); + TclNewIntObj(incrPtr, increment); Tcl_IncrRefCount(incrPtr); pcAdjustment = 3; @@ -3720,7 +3736,7 @@ TEBCresume( TRACE(("%u %ld => ", opnd, increment)); if (Tcl_IsShared(objPtr)) { objPtr->refCount--; /* We know it's shared. */ - objResultPtr = Tcl_NewWideIntObj(w+increment); + TclNewIntObj(objResultPtr, w + increment); Tcl_IncrRefCount(objResultPtr); varPtr->value.objPtr = objResultPtr; } else { @@ -4448,7 +4464,7 @@ TEBCresume( CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; TclNewObj(objResultPtr); - if (corPtr && !(corPtr->cmdPtr->flags & CMD_IS_DELETED)) { + if (corPtr && !(corPtr->cmdPtr->flags & CMD_DYING)) { Tcl_GetCommandFullName(interp, (Tcl_Command) corPtr->cmdPtr, objResultPtr); } @@ -4508,6 +4524,18 @@ TEBCresume( TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS))); cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS); if (cmd == NULL) { + goto instOriginError; + } + origCmd = TclGetOriginalCommand(cmd); + if (origCmd == NULL) { + origCmd = cmd; + } + + TclNewObj(objResultPtr); + Tcl_GetCommandFullName(interp, origCmd, objResultPtr); + if (TclCheckEmptyString(objResultPtr) == TCL_EMPTYSTRING_YES ) { + Tcl_DecrRefCount(objResultPtr); + instOriginError: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid command name \"%s\"", TclGetString(OBJ_AT_TOS))); DECACHE_STACK_INFO(); @@ -4517,12 +4545,6 @@ TEBCresume( TRACE_APPEND(("ERROR: not command\n")); goto gotError; } - origCmd = TclGetOriginalCommand(cmd); - if (origCmd == NULL) { - origCmd = cmd; - } - TclNewObj(objResultPtr); - Tcl_GetCommandFullName(interp, origCmd, objResultPtr); TRACE_APPEND(("\"%.30s\"", O2S(OBJ_AT_TOS))); NEXT_INST_F(1, 1, 1); } @@ -4841,13 +4863,19 @@ TEBCresume( */ if ((TclListObjGetElements(interp, valuePtr, &objc, &objv) == TCL_OK) - && !TclHasIntRep(value2Ptr, &tclListType) - && (TclGetIntForIndexM(NULL, value2Ptr, objc-1, - &index) == TCL_OK)) { - TclDecrRefCount(value2Ptr); - tosPtr--; - pcAdjustment = 1; - goto lindexFastPath; + && !TclHasIntRep(value2Ptr, &tclListType)) { + int code; + + DECACHE_STACK_INFO(); + code = TclGetIntForIndexM(interp, value2Ptr, objc-1, &index); + CACHE_STACK_INFO(); + if (code == TCL_OK) { + TclDecrRefCount(value2Ptr); + tosPtr--; + pcAdjustment = 1; + goto lindexFastPath; + } + Tcl_ResetResult(interp); } objResultPtr = TclLindexList(interp, valuePtr, value2Ptr); @@ -5048,7 +5076,7 @@ TEBCresume( if (toIdx == TCL_INDEX_NONE) { emptyList: - objResultPtr = Tcl_NewObj(); + TclNewObj(objResultPtr); TRACE_APPEND(("\"%.30s\"", O2S(objResultPtr))); NEXT_INST_F(9, 1, 1); } @@ -5282,10 +5310,13 @@ TEBCresume( */ length = Tcl_GetCharLength(valuePtr); + DECACHE_STACK_INFO(); if (TclGetIntForIndexM(interp, value2Ptr, length-1, &index)!=TCL_OK) { + CACHE_STACK_INFO(); TRACE_ERROR(interp); goto gotError; } + CACHE_STACK_INFO(); if ((index < 0) || (index >= length)) { TclNewObj(objResultPtr); @@ -5305,7 +5336,7 @@ TEBCresume( * practical use. */ if (ch == -1) { - objResultPtr = Tcl_NewObj(); + TclNewObj(objResultPtr); } else { length = Tcl_UniCharToUtf(ch, buf); if ((ch >= 0xD800) && (length < 3)) { @@ -5322,13 +5353,21 @@ TEBCresume( TRACE(("\"%.20s\" %.20s %.20s =>", O2S(OBJ_AT_DEPTH(2)), O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS))); length = Tcl_GetCharLength(OBJ_AT_DEPTH(2)) - 1; + + DECACHE_STACK_INFO(); if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length, - &fromIdx) != TCL_OK - || TclGetIntForIndexM(interp, OBJ_AT_TOS, length, + &fromIdx) != TCL_OK) { + CACHE_STACK_INFO(); + TRACE_ERROR(interp); + goto gotError; + } + if (TclGetIntForIndexM(interp, OBJ_AT_TOS, length, &toIdx) != TCL_OK) { + CACHE_STACK_INFO(); TRACE_ERROR(interp); goto gotError; } + CACHE_STACK_INFO(); if (fromIdx < 0) { fromIdx = 0; @@ -5411,14 +5450,17 @@ TEBCresume( endIdx = Tcl_GetCharLength(valuePtr) - 1; TRACE(("\"%.20s\" %s %s \"%.20s\" => ", O2S(valuePtr), O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), O2S(value3Ptr))); + DECACHE_STACK_INFO(); if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, endIdx, &fromIdx) != TCL_OK || TclGetIntForIndexM(interp, OBJ_AT_TOS, endIdx, &toIdx) != TCL_OK) { + CACHE_STACK_INFO(); TclDecrRefCount(value3Ptr); TRACE_ERROR(interp); goto gotError; } + CACHE_STACK_INFO(); TclDecrRefCount(OBJ_AT_TOS); (void) POP_OBJECT(); TclDecrRefCount(OBJ_AT_TOS); @@ -6114,7 +6156,7 @@ TEBCresume( wideResultOfArithmetic: TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr))); if (Tcl_IsShared(valuePtr)) { - objResultPtr = Tcl_NewWideIntObj(wResult); + TclNewIntObj(objResultPtr, wResult); TRACE(("%s\n", O2S(objResultPtr))); NEXT_INST_F(1, 2, 1); } @@ -6385,8 +6427,8 @@ TEBCresume( if (TclHasIntRep(valuePtr, &tclBooleanType)) { objResultPtr = TCONST(1); } else { - int result = (TclSetBooleanFromAny(NULL, valuePtr) == TCL_OK); - objResultPtr = TCONST(result); + int res = (TclSetBooleanFromAny(NULL, valuePtr) == TCL_OK); + objResultPtr = TCONST(res); } TRACE_WITH_OBJ(("\"%.30s\" => ", O2S(valuePtr)), objResultPtr); NEXT_INST_F(1, 0, 1); @@ -6580,7 +6622,7 @@ TEBCresume( } { ForeachInfo *infoPtr; - Tcl_Obj *listPtr, **elements, *tmpPtr; + Tcl_Obj *listPtr, **elements; ForeachVarList *varListPtr; int numLists, listLen, numVars; int listTmpDepth; @@ -7004,9 +7046,9 @@ TEBCresume( break; } if (valuePtr == NULL) { - Tcl_DictObjPut(NULL, dictPtr, OBJ_AT_TOS,Tcl_NewIntObj(opnd)); + Tcl_DictObjPut(NULL, dictPtr, OBJ_AT_TOS, Tcl_NewWideIntObj(opnd)); } else { - value2Ptr = Tcl_NewIntObj(opnd); + TclNewIntObj(value2Ptr, opnd); Tcl_IncrRefCount(value2Ptr); if (Tcl_IsShared(valuePtr)) { valuePtr = Tcl_DuplicateObj(valuePtr); @@ -7522,7 +7564,7 @@ TEBCresume( default: Tcl_Panic("clockRead instruction with unknown clock#"); } - objResultPtr = Tcl_NewWideIntObj(wval); + TclNewIntObj(objResultPtr, wval); TRACE_WITH_OBJ(("=> "), objResultPtr); NEXT_INST_F(2, 0, 1); } @@ -9677,7 +9719,7 @@ EvalStatsCmd( #define Percent(a,b) ((a) * 100.0 / (b)) - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); Tcl_IncrRefCount(objPtr); numInstructions = 0.0; |
