summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c54
1 files changed, 48 insertions, 6 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 443fb85..df88bf9 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -202,6 +202,9 @@ typedef struct TEBCdata {
#define PUSH_TAUX_OBJ(objPtr) \
do { \
+ if (auxObjList) { \
+ objPtr->length += auxObjList->length; \
+ } \
objPtr->internalRep.ptrAndLongRep.ptr = auxObjList; \
auxObjList = objPtr; \
} while (0)
@@ -2320,7 +2323,7 @@ TEBCresume(
goto instLoadScalar1;
} else if (inst == INST_PUSH1) {
PUSH_OBJECT(codePtr->objArrayPtr[TclGetUInt1AtPtr(pc+1)]);
- TRACE_WITH_OBJ(("%u => ", TclGetInt1AtPtr(pc+1)), OBJ_AT_TOS);
+ TRACE_WITH_OBJ(("%u => ", TclGetUInt1AtPtr(pc+1)), OBJ_AT_TOS);
inst = *(pc += 2);
goto peepholeStart;
} else if (inst == INST_START_CMD) {
@@ -2715,9 +2718,26 @@ TEBCresume(
TclNewObj(objPtr);
objPtr->internalRep.ptrAndLongRep.value = CURR_DEPTH;
+ objPtr->length = 0;
PUSH_TAUX_OBJ(objPtr);
NEXT_INST_F(1, 0, 0);
+ case INST_VERIFY : {
+#ifdef TCL_COMPILE_DEBUG
+ /*
+ * This is how deep the compiler thought the stack would be,
+ * assuming no expansion.
+ */
+ int estimate = TclGetUInt4AtPtr(pc+1);
+
+ if (CURR_DEPTH != estimate + (auxObjList ? auxObjList->length : 0)) {
+ Tcl_Panic("Bad stack estimate = %d; truth = %ld", estimate,
+ CURR_DEPTH - (auxObjList ? auxObjList->length : 0));
+ }
+#endif
+ NEXT_INST_F(5, 0, 0);
+ }
+
case INST_EXPAND_DROP:
/*
* Drops an element of the auxObjList, popping stack elements to
@@ -2738,6 +2758,18 @@ TEBCresume(
int i;
ptrdiff_t moved;
+#ifdef TCL_COMPILE_DEBUG
+ /*
+ * This is how deep the compiler thought the stack would be,
+ * assuming no expansion.
+ */
+ int estimate = TclGetInt4AtPtr(pc+1);
+
+ if (CURR_DEPTH != estimate + auxObjList->length) {
+ Tcl_Panic("Bad stack estimate = %d; truth = %ld", estimate,
+ CURR_DEPTH - auxObjList->length);
+ }
+#endif
/*
* Make sure that the element at stackTop is a list; if not, just
* leave with an error. Note that the element from the expand list
@@ -2759,7 +2791,11 @@ TEBCresume(
* stack depth, as seen by the compiler.
*/
- length = objc + (codePtr->maxStackDepth - TclGetInt4AtPtr(pc+1));
+ auxObjList->length += objc - 1;
+ if ((objc > 1) && (auxObjList->length > 0)) {
+ length = auxObjList->length /* Total expansion room we need */
+ + codePtr->maxStackDepth /* Beyond the original max */
+ - CURR_DEPTH; /* Relative to where we are */
DECACHE_STACK_INFO();
moved = GrowEvaluationStack(iPtr->execEnvPtr, length, 1)
- (Tcl_Obj **) TD;
@@ -2776,6 +2812,7 @@ TEBCresume(
catchTop += moved;
tosPtr += moved;
}
+ }
/*
* Expand the list at stacktop onto the stack; free the list. Knowing
@@ -2975,7 +3012,7 @@ TEBCresume(
#endif
case INST_INVOKE_REPLACE:
- objc = TclGetUInt4AtPtr(pc+1);
+ objc = TclGetUInt4AtPtr(pc+1) - 1;
opnd = TclGetUInt1AtPtr(pc+5);
objPtr = POP_OBJECT();
objv = &OBJ_AT_DEPTH(objc-1);
@@ -4227,7 +4264,7 @@ TEBCresume(
} else {
TRACE(("%d => %.20s false, new pc %u\n", jmpOffset[0],
O2S(valuePtr),
- (unsigned)(pc + jmpOffset[1] - codePtr->codeStart)));
+ (unsigned)(pc + jmpOffset[0] - codePtr->codeStart)));
}
}
#endif
@@ -6150,6 +6187,11 @@ TEBCresume(
*/
pc += 5;
+#ifdef TCL_COMPILE_DEBUG
+ if (*pc == INST_VERIFY) {
+ pc +=5;
+ }
+#endif
if (*pc == INST_JUMP_FALSE1) {
NEXT_INST_F((continueLoop? 2 : TclGetInt1AtPtr(pc+1)), 0, 0);
} else {
@@ -6246,7 +6288,7 @@ TEBCresume(
case INST_DICT_EXISTS: {
register Tcl_Interp *interp2 = interp;
- opnd = TclGetUInt4AtPtr(pc+1);
+ opnd = TclGetUInt4AtPtr(pc+1) - 1;
TRACE(("%u => ", opnd));
dictPtr = OBJ_AT_DEPTH(opnd);
if (*pc == INST_DICT_EXISTS) {
@@ -6302,7 +6344,7 @@ TEBCresume(
case INST_DICT_SET:
case INST_DICT_UNSET:
case INST_DICT_INCR_IMM:
- opnd = TclGetUInt4AtPtr(pc+1);
+ opnd = TclGetUInt4AtPtr(pc+1) - (*pc == INST_DICT_SET);
opnd2 = TclGetUInt4AtPtr(pc+5);
varPtr = LOCAL(opnd2);