summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--generic/tclExecute.c304
-rw-r--r--generic/tclInt.h8
3 files changed, 157 insertions, 162 deletions
diff --git a/ChangeLog b/ChangeLog
index 9f64e6f..47e6b86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2003-09-23 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c:
+ * generic/tclInt.h: changed the evaluation-stack addressing mode,
+ from array-style to pointer-style; the catch stack and evaluation
+ stack are now contiguous in memory. [Patch 457449]
+
2003-09-23 Don Porter <dgp@users.sourceforge.net>
* library/init.tcl (auto_load, auto_import): Expanded Eric Melski's
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 5eb2262..d0dfa0f 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclExecute.c,v 1.107 2003/09/19 18:09:41 msofer Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.108 2003/09/23 14:48:49 msofer Exp $
*/
#include "tclInt.h"
@@ -151,7 +151,7 @@ long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 };
if ((result) > 0) {\
PUSH_OBJECT(objResultPtr);\
} else {\
- stackPtr[++stackTop] = objResultPtr;\
+ *(++tosPtr) = objResultPtr;\
}\
} \
pc += (pcAdjustment);\
@@ -197,11 +197,10 @@ long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 };
*/
#define CACHE_STACK_INFO() \
- stackPtr = eePtr->stackPtr; \
- stackTop = eePtr->stackTop
+ tosPtr = eePtr->tosPtr
#define DECACHE_STACK_INFO() \
- eePtr->stackTop = stackTop
+ eePtr->tosPtr = tosPtr
/*
@@ -220,10 +219,10 @@ long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 };
*/
#define PUSH_OBJECT(objPtr) \
- Tcl_IncrRefCount(stackPtr[++stackTop] = (objPtr))
+ Tcl_IncrRefCount(*(++tosPtr) = (objPtr))
#define POP_OBJECT() \
- (stackPtr[stackTop--])
+ *(tosPtr--)
/*
* Macros used to trace instruction execution. The macros TRACE,
@@ -234,7 +233,8 @@ long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 };
#ifdef TCL_COMPILE_DEBUG
# define TRACE(a) \
if (traceInstructions) { \
- fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels, stackTop, \
+ fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels, \
+ (tosPtr - eePtr->stackPtr), \
(unsigned int)(pc - codePtr->codeStart), \
GetOpcodeName(pc)); \
printf a; \
@@ -245,7 +245,8 @@ long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 };
}
# define TRACE_WITH_OBJ(a, objPtr) \
if (traceInstructions) { \
- fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels, stackTop, \
+ fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels, \
+ (tosPtr - eePtr->stackPtr), \
(unsigned int)(pc - codePtr->codeStart), \
GetOpcodeName(pc)); \
printf a; \
@@ -507,8 +508,8 @@ TclCreateExecEnv(interp)
eePtr->stackPtr = stackPtr;
stackPtr[-1] = (Tcl_Obj *) ((char *) 1);
- eePtr->stackTop = -1;
- eePtr->stackEnd = (TCL_STACK_INITIAL_SIZE - 2);
+ eePtr->tosPtr = stackPtr - 1;
+ eePtr->endPtr = stackPtr + (TCL_STACK_INITIAL_SIZE - 2);
eePtr->errorInfo = Tcl_NewStringObj("::errorInfo", -1);
Tcl_IncrRefCount(eePtr->errorInfo);
@@ -608,11 +609,11 @@ GrowEvaluationStack(eePtr)
* stack to enlarge. */
{
/*
- * The current Tcl stack elements are stored from eePtr->stackPtr[0]
- * to eePtr->stackPtr[eePtr->stackEnd] (inclusive).
+ * The current Tcl stack elements are stored from *(eePtr->stackPtr)
+ * to *(eePtr->endPtr) (inclusive).
*/
- int currElems = (eePtr->stackEnd + 1);
+ int currElems = (eePtr->endPtr - eePtr->stackPtr + 1);
int newElems = 2*currElems;
int currBytes = currElems * sizeof(Tcl_Obj *);
int newBytes = 2*currBytes;
@@ -648,7 +649,8 @@ GrowEvaluationStack(eePtr)
}
eePtr->stackPtr = newStackPtr;
- eePtr->stackEnd = (newElems - 2); /* index of last usable item */
+ eePtr->endPtr = newStackPtr + (newElems - 2); /* index of last usable item */
+ eePtr->tosPtr += (newStackPtr - oldStackPtr);
newStackPtr[-1] = (Tcl_Obj *) ((char *) 1);
}
@@ -1055,15 +1057,14 @@ TclExecuteByteCode(interp, codePtr)
Interp *iPtr = (Interp *) interp;
ExecEnv *eePtr = iPtr->execEnvPtr;
/* Points to the execution environment. */
- register Tcl_Obj **stackPtr = eePtr->stackPtr;
- /* Cached evaluation stack base pointer. */
- register int stackTop = eePtr->stackTop;
- /* Cached top index of evaluation stack. */
+ int *catchStackPtr; /* start of the catch stack */
+ int catchTop = -1;
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
register unsigned char *pc = codePtr->codeStart;
/* The current program counter. */
int opnd; /* Current instruction's operand byte(s). */
int pcAdjustment; /* Hold pc adjustment after instruction. */
- int initStackTop = stackTop;/* Stack top at start of execution. */
+ int initStackTop; /* Stack top at start of execution. */
ExceptionRange *rangePtr; /* Points to closest loop or catch exception
* range enclosing the pc. Used by various
* instructions and processCatch to
@@ -1093,15 +1094,11 @@ TclExecuteByteCode(interp, codePtr)
* allocated space but uses dynamically-allocated storage if needed.
*/
-#define STATIC_CATCH_STACK_SIZE 4
- int (catchStackStorage[STATIC_CATCH_STACK_SIZE]);
- int *catchStackPtr = catchStackStorage;
- int catchTop = -1;
#ifdef TCL_COMPILE_DEBUG
if (tclTraceExec >= 2) {
PrintByteCodeInfo(codePtr);
- fprintf(stdout, " Starting stack top=%d\n", eePtr->stackTop);
+ fprintf(stdout, " Starting stack top=%d\n", initStackTop);
fflush(stdout);
}
opnd = 0; /* Init. avoids compiler warning. */
@@ -1112,24 +1109,23 @@ TclExecuteByteCode(interp, codePtr)
#endif
/*
+ * The execution uses a unified stack: first the catch stack, immediately
+ * above it the execution stack.
+ *
* Make sure the catch stack is large enough to hold the maximum number
- * of catch commands that could ever be executing at the same time. This
- * will be no more than the exception range array's depth.
- */
-
- if (codePtr->maxExceptDepth > STATIC_CATCH_STACK_SIZE) {
- catchStackPtr = (int *)
- ckalloc(codePtr->maxExceptDepth * sizeof(int));
- }
-
- /*
- * Make sure the stack has enough room to execute this ByteCode.
+ * of catch commands that could ever be executing at the same time (this
+ * will be no more than the exception range array's depth).
+ * Make sure the execution stack is large enough to execute this ByteCode.
*/
- while ((stackTop + codePtr->maxStackDepth) > eePtr->stackEnd) {
+ catchStackPtr = (int *)(eePtr->tosPtr + 1);
+ while ((catchStackPtr + codePtr->maxExceptDepth + codePtr->maxStackDepth)
+ > (int *) eePtr->endPtr) {
GrowEvaluationStack(eePtr);
- stackPtr = eePtr->stackPtr;
+ catchStackPtr = (int *)(eePtr->tosPtr + 1);
}
+ tosPtr = (Tcl_Obj **) (catchStackPtr + codePtr->maxExceptDepth - 1);
+ initStackTop = tosPtr - eePtr->stackPtr;
/*
* Loop executing instructions until a "done" instruction, a
@@ -1151,7 +1147,7 @@ TclExecuteByteCode(interp, codePtr)
cleanupV_pushObjResultPtr:
switch (cleanup) {
case 0:
- stackPtr[++stackTop] = (objResultPtr);
+ *(++tosPtr) = (objResultPtr);
goto cleanup0;
default:
cleanup -= 2;
@@ -1165,10 +1161,10 @@ TclExecuteByteCode(interp, codePtr)
TclDecrRefCount(valuePtr);
case 1:
cleanup1_pushObjResultPtr:
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
TclDecrRefCount(valuePtr);
}
- stackPtr[stackTop] = objResultPtr;
+ *tosPtr = objResultPtr;
goto cleanup0;
cleanupV:
@@ -1198,9 +1194,10 @@ TclExecuteByteCode(interp, codePtr)
cleanup0:
#ifdef TCL_COMPILE_DEBUG
- ValidatePcAndStackTop(codePtr, pc, stackTop, initStackTop);
+ ValidatePcAndStackTop(codePtr, pc, (tosPtr - eePtr->stackPtr),
+ initStackTop);
if (traceInstructions) {
- fprintf(stdout, "%2d: %2d ", iPtr->numLevels, stackTop);
+ fprintf(stdout, "%2d: %2d ", iPtr->numLevels, (tosPtr - eePtr->stackPtr));
TclPrintInstruction(codePtr, pc);
fflush(stdout);
}
@@ -1218,8 +1215,8 @@ TclExecuteByteCode(interp, codePtr)
}
result = TCL_RETURN;
case INST_DONE:
- if (stackTop <= initStackTop) {
- stackTop--;
+ if (tosPtr <= eePtr->stackPtr + initStackTop) {
+ tosPtr--;
goto abnormalReturn;
}
@@ -1230,7 +1227,7 @@ TclExecuteByteCode(interp, codePtr)
* by "processCatch" or "abnormalReturn".
*/
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
Tcl_SetObjResult(interp, valuePtr);
#ifdef TCL_COMPILE_DEBUG
TRACE_WITH_OBJ(("=> return code=%d, result=", result),
@@ -1252,19 +1249,19 @@ TclExecuteByteCode(interp, codePtr)
NEXT_INST_F(5, 0, 1);
case INST_POP:
- TRACE_WITH_OBJ(("=> discarding "), stackPtr[stackTop]);
+ TRACE_WITH_OBJ(("=> discarding "), *tosPtr);
valuePtr = POP_OBJECT();
TclDecrRefCount(valuePtr);
NEXT_INST_F(1, 0, 0);
case INST_DUP:
- objResultPtr = stackPtr[stackTop];
+ objResultPtr = *tosPtr;
TRACE_WITH_OBJ(("=> "), objResultPtr);
NEXT_INST_F(1, 0, 1);
case INST_OVER:
opnd = TclGetUInt4AtPtr( pc+1 );
- objResultPtr = stackPtr[ stackTop - opnd ];
+ objResultPtr = *(tosPtr - opnd);
TRACE_WITH_OBJ(("=> "), objResultPtr);
NEXT_INST_F(5, 0, 1);
@@ -1272,6 +1269,7 @@ TclExecuteByteCode(interp, codePtr)
opnd = TclGetUInt1AtPtr(pc+1);
{
int totalLen = 0;
+ Tcl_Obj **currPtr;
/*
* Concatenate strings (with no separators) from the top
@@ -1279,8 +1277,9 @@ TclExecuteByteCode(interp, codePtr)
* First, determine how many characters are needed.
*/
- for (i = (stackTop - (opnd-1)); i <= stackTop; i++) {
- bytes = Tcl_GetStringFromObj(stackPtr[i], &length);
+ for (currPtr = tosPtr - (opnd-1); currPtr <= tosPtr;
+ currPtr++) {
+ bytes = Tcl_GetStringFromObj(*currPtr, &length);
if (bytes != NULL) {
totalLen += length;
}
@@ -1296,9 +1295,9 @@ TclExecuteByteCode(interp, codePtr)
char *p = (char *) ckalloc((unsigned) (totalLen + 1));
objResultPtr->bytes = p;
objResultPtr->length = totalLen;
- for (i = (stackTop - (opnd-1)); i <= stackTop; i++) {
- valuePtr = stackPtr[i];
- bytes = Tcl_GetStringFromObj(valuePtr, &length);
+ for (currPtr = tosPtr - (opnd-1); currPtr <= tosPtr;
+ currPtr++) {
+ bytes = Tcl_GetStringFromObj(*currPtr, &length);
if (bytes != NULL) {
memcpy((VOID *) p, (VOID *) bytes,
(size_t) length);
@@ -1339,7 +1338,7 @@ TclExecuteByteCode(interp, codePtr)
* trace and command invokations.)
*/
- objv = &(stackPtr[stackTop - (objc-1)]);
+ objv = (tosPtr - (objc-1));
#ifdef TCL_COMPILE_DEBUG
if (tclTraceExec >= 2) {
@@ -1402,7 +1401,7 @@ TclExecuteByteCode(interp, codePtr)
* trace procedures.
*/
- preservedStackRefCountPtr = (char **) (stackPtr-1);
+ preservedStackRefCountPtr = (char **) (eePtr->stackPtr-1);
++*preservedStackRefCountPtr;
/*
@@ -1468,7 +1467,7 @@ TclExecuteByteCode(interp, codePtr)
* checkForCatch! DO NOT OPTIMISE!
*/
- objPtr = stackPtr[stackTop];
+ objPtr = *tosPtr;
DECACHE_STACK_INFO();
result = TclCompEvalObj(interp, objPtr);
CACHE_STACK_INFO();
@@ -1506,7 +1505,7 @@ TclExecuteByteCode(interp, codePtr)
}
case INST_EXPR_STK:
- objPtr = stackPtr[stackTop];
+ objPtr = *tosPtr;
DECACHE_STACK_INFO();
Tcl_ResetResult(interp);
result = Tcl_ExprObj(interp, objPtr, &valuePtr);
@@ -1577,8 +1576,8 @@ TclExecuteByteCode(interp, codePtr)
case INST_LOAD_ARRAY_STK:
cleanup = 2;
- part2 = Tcl_GetString(stackPtr[stackTop]); /* element name */
- objPtr = stackPtr[stackTop-1]; /* array name */
+ part2 = Tcl_GetString(*tosPtr); /* element name */
+ objPtr = *(tosPtr - 1); /* array name */
TRACE(("\"%.30s(%.30s)\" => ", O2S(objPtr), part2));
goto doLoadStk;
@@ -1586,7 +1585,7 @@ TclExecuteByteCode(interp, codePtr)
case INST_LOAD_SCALAR_STK:
cleanup = 1;
part2 = NULL;
- objPtr = stackPtr[stackTop]; /* variable name */
+ objPtr = *tosPtr; /* variable name */
TRACE(("\"%.30s\" => ", O2S(objPtr)));
doLoadStk:
@@ -1624,7 +1623,7 @@ TclExecuteByteCode(interp, codePtr)
pcAdjustment = 2;
doLoadArray:
- part2 = TclGetString(stackPtr[stackTop]);
+ part2 = TclGetString(*tosPtr);
arrayPtr = &(varFramePtr->compiledLocals[opnd]);
part1 = arrayPtr->name;
while (TclIsVarLink(arrayPtr)) {
@@ -1685,45 +1684,45 @@ TclExecuteByteCode(interp, codePtr)
*/
case INST_LAPPEND_STK:
- valuePtr = stackPtr[stackTop]; /* value to append */
+ valuePtr = *tosPtr; /* value to append */
part2 = NULL;
storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE
| TCL_LIST_ELEMENT | TCL_TRACE_READS);
goto doStoreStk;
case INST_LAPPEND_ARRAY_STK:
- valuePtr = stackPtr[stackTop]; /* value to append */
- part2 = TclGetString(stackPtr[stackTop - 1]);
+ valuePtr = *tosPtr; /* value to append */
+ part2 = TclGetString(*(tosPtr - 1));
storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE
| TCL_LIST_ELEMENT | TCL_TRACE_READS);
goto doStoreStk;
case INST_APPEND_STK:
- valuePtr = stackPtr[stackTop]; /* value to append */
+ valuePtr = *tosPtr; /* value to append */
part2 = NULL;
storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
goto doStoreStk;
case INST_APPEND_ARRAY_STK:
- valuePtr = stackPtr[stackTop]; /* value to append */
- part2 = TclGetString(stackPtr[stackTop - 1]);
+ valuePtr = *tosPtr; /* value to append */
+ part2 = TclGetString(*(tosPtr - 1));
storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
goto doStoreStk;
case INST_STORE_ARRAY_STK:
- valuePtr = stackPtr[stackTop];
- part2 = TclGetString(stackPtr[stackTop - 1]);
+ valuePtr = *tosPtr;
+ part2 = TclGetString(*(tosPtr - 1));
storeFlags = TCL_LEAVE_ERR_MSG;
goto doStoreStk;
case INST_STORE_STK:
case INST_STORE_SCALAR_STK:
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
part2 = NULL;
storeFlags = TCL_LEAVE_ERR_MSG;
doStoreStk:
- objPtr = stackPtr[stackTop - 1 - (part2 != NULL)]; /* variable name */
+ objPtr = *(tosPtr - 1 - (part2 != NULL)); /* variable name */
part1 = TclGetString(objPtr);
#ifdef TCL_COMPILE_DEBUG
if (part2 == NULL) {
@@ -1785,8 +1784,8 @@ TclExecuteByteCode(interp, codePtr)
storeFlags = TCL_LEAVE_ERR_MSG;
doStoreArray:
- valuePtr = stackPtr[stackTop];
- part2 = TclGetString(stackPtr[stackTop - 1]);
+ valuePtr = *tosPtr;
+ part2 = TclGetString(*(tosPtr - 1));
arrayPtr = &(varFramePtr->compiledLocals[opnd]);
part1 = arrayPtr->name;
TRACE(("%u \"%.30s\" <- \"%.30s\" => ",
@@ -1842,7 +1841,7 @@ TclExecuteByteCode(interp, codePtr)
storeFlags = TCL_LEAVE_ERR_MSG;
doStoreScalar:
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
varPtr = &(varFramePtr->compiledLocals[opnd]);
part1 = varPtr->name;
TRACE(("%u <- \"%.30s\" => ", opnd, O2S(valuePtr)));
@@ -1868,7 +1867,7 @@ TclExecuteByteCode(interp, codePtr)
* the stack top remains pointing to the same Tcl_Obj.
*/
valuePtr = varPtr->value.objPtr;
- objResultPtr = stackPtr[stackTop];
+ objResultPtr = *tosPtr;
if (valuePtr != objResultPtr) {
if (valuePtr != NULL) {
TclDecrRefCount(valuePtr);
@@ -1927,7 +1926,7 @@ TclExecuteByteCode(interp, codePtr)
case INST_INCR_SCALAR_STK:
case INST_INCR_STK:
opnd = TclGetUInt1AtPtr(pc+1);
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
if (valuePtr->typePtr == &tclIntType) {
i = valuePtr->internalRep.longValue;
isWide = 0;
@@ -1946,7 +1945,7 @@ TclExecuteByteCode(interp, codePtr)
}
isWide = (valuePtr->typePtr == &tclWideIntType);
}
- stackTop--;
+ tosPtr--;
TclDecrRefCount(valuePtr);
switch (*pc) {
case INST_INCR_SCALAR1:
@@ -1970,13 +1969,13 @@ TclExecuteByteCode(interp, codePtr)
doIncrStk:
if ((*pc == INST_INCR_ARRAY_STK_IMM)
|| (*pc == INST_INCR_ARRAY_STK)) {
- part2 = TclGetString(stackPtr[stackTop]);
- objPtr = stackPtr[stackTop - 1];
+ part2 = TclGetString(*tosPtr);
+ objPtr = *(tosPtr - 1);
TRACE(("\"%.30s(%.30s)\" (by %ld) => ",
O2S(objPtr), part2, i));
} else {
part2 = NULL;
- objPtr = stackPtr[stackTop];
+ objPtr = *tosPtr;
TRACE(("\"%.30s\" (by %ld) => ", O2S(objPtr), i));
}
part1 = TclGetString(objPtr);
@@ -2002,7 +2001,7 @@ TclExecuteByteCode(interp, codePtr)
pcAdjustment = 3;
doIncrArray:
- part2 = TclGetString(stackPtr[stackTop]);
+ part2 = TclGetString(*tosPtr);
arrayPtr = &(varFramePtr->compiledLocals[opnd]);
part1 = arrayPtr->name;
while (TclIsVarLink(arrayPtr)) {
@@ -2145,7 +2144,7 @@ TclExecuteByteCode(interp, codePtr)
{
int b;
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
if (valuePtr->typePtr == &tclIntType) {
b = (valuePtr->internalRep.longValue != 0);
} else if (valuePtr->typePtr == &tclDoubleType) {
@@ -2197,8 +2196,8 @@ TclExecuteByteCode(interp, codePtr)
char *s;
Tcl_ObjType *t1Ptr, *t2Ptr;
- value2Ptr = stackPtr[stackTop];
- valuePtr = stackPtr[stackTop - 1];;
+ value2Ptr = *tosPtr;
+ valuePtr = *(tosPtr - 1);
t1Ptr = valuePtr->typePtr;
t2Ptr = value2Ptr->typePtr;
@@ -2294,12 +2293,12 @@ TclExecuteByteCode(interp, codePtr)
*/
opnd = TclGetUInt4AtPtr(pc+1);
- objResultPtr = Tcl_NewListObj(opnd, &(stackPtr[stackTop - (opnd-1)]));
+ objResultPtr = Tcl_NewListObj(opnd, (tosPtr - (opnd-1)));
TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
NEXT_INST_V(5, opnd, 1);
case INST_LIST_LENGTH:
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
result = Tcl_ListObjLength(interp, valuePtr, &length);
if (result != TCL_OK) {
@@ -2317,8 +2316,8 @@ TclExecuteByteCode(interp, codePtr)
/*
* Pop the two operands
*/
- value2Ptr = stackPtr[stackTop];
- valuePtr = stackPtr[stackTop- 1];
+ value2Ptr = *tosPtr;
+ valuePtr = *(tosPtr - 1);
/*
* Extract the desired list element
@@ -2354,8 +2353,8 @@ TclExecuteByteCode(interp, codePtr)
/*
* Do the 'lindex' operation.
*/
- objResultPtr = TclLindexFlat(interp, stackPtr[stackTop - numIdx],
- numIdx, stackPtr + stackTop - numIdx + 1);
+ objResultPtr = TclLindexFlat(interp, *(tosPtr - numIdx),
+ numIdx, tosPtr - numIdx + 1);
/*
* Check for errors
@@ -2395,13 +2394,13 @@ TclExecuteByteCode(interp, codePtr)
/*
* Get the new element value.
*/
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
/*
* Compute the new variable value
*/
objResultPtr = TclLsetFlat(interp, value2Ptr, numIdx,
- stackPtr + stackTop - numIdx, valuePtr);
+ tosPtr - numIdx, valuePtr);
/*
@@ -2434,8 +2433,8 @@ TclExecuteByteCode(interp, codePtr)
/*
* Get the new element value, and the index list
*/
- valuePtr = stackPtr[stackTop];
- value2Ptr = stackPtr[stackTop - 1];
+ valuePtr = *tosPtr;
+ value2Ptr = *(tosPtr - 1);
/*
* Compute the new variable value
@@ -2471,8 +2470,8 @@ TclExecuteByteCode(interp, codePtr)
*/
int iResult;
- value2Ptr = stackPtr[stackTop];
- valuePtr = stackPtr[stackTop - 1];
+ value2Ptr = *tosPtr;
+ valuePtr = *(tosPtr - 1);
if (valuePtr == value2Ptr) {
/*
@@ -2534,8 +2533,8 @@ TclExecuteByteCode(interp, codePtr)
CONST char *s1, *s2;
int s1len, s2len, iResult;
- value2Ptr = stackPtr[stackTop];
- valuePtr = stackPtr[stackTop - 1];
+ value2Ptr = *tosPtr;
+ valuePtr = *(tosPtr - 1);
/*
* The comparison function should compare up to the
@@ -2604,7 +2603,7 @@ TclExecuteByteCode(interp, codePtr)
{
int length1;
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
if (valuePtr->typePtr == &tclByteArrayType) {
(void) Tcl_GetByteArrayFromObj(valuePtr, &length1);
@@ -2624,8 +2623,8 @@ TclExecuteByteCode(interp, codePtr)
int index;
bytes = NULL; /* lint */
- value2Ptr = stackPtr[stackTop];
- valuePtr = stackPtr[stackTop - 1];
+ value2Ptr = *tosPtr;
+ valuePtr = *(tosPtr - 1);
/*
* If we have a ByteArray object, avoid indexing in the
@@ -2683,8 +2682,8 @@ TclExecuteByteCode(interp, codePtr)
int nocase, match;
nocase = TclGetInt1AtPtr(pc+1);
- valuePtr = stackPtr[stackTop]; /* String */
- value2Ptr = stackPtr[stackTop - 1]; /* Pattern */
+ valuePtr = *tosPtr; /* String */
+ value2Ptr = *(tosPtr - 1); /* Pattern */
/*
* Check that at least one of the objects is Unicode before
@@ -2740,8 +2739,8 @@ TclExecuteByteCode(interp, codePtr)
double d2 = 0.0; /* Init. avoids compiler warning. */
long iResult = 0; /* Init. avoids compiler warning. */
- value2Ptr = stackPtr[stackTop];
- valuePtr = stackPtr[stackTop - 1];
+ value2Ptr = *tosPtr;
+ valuePtr = *(tosPtr - 1);
if (valuePtr == value2Ptr) {
/*
@@ -2970,8 +2969,8 @@ TclExecuteByteCode(interp, codePtr)
Tcl_WideInt w2, wResult = W0;
int doWide = 0;
- value2Ptr = stackPtr[stackTop];
- valuePtr = stackPtr[stackTop - 1];
+ value2Ptr = *tosPtr;
+ valuePtr = *(tosPtr - 1);
if (valuePtr->typePtr == &tclIntType) {
i = valuePtr->internalRep.longValue;
} else if (valuePtr->typePtr == &tclWideIntType) {
@@ -3215,8 +3214,8 @@ TclExecuteByteCode(interp, codePtr)
Tcl_WideInt wResult = W0; /* Init. avoids compiler warning. */
int doWide = 0; /* 1 if doing wide arithmetic. */
- value2Ptr = stackPtr[stackTop];
- valuePtr = stackPtr[stackTop - 1];
+ value2Ptr = *tosPtr;
+ valuePtr = *(tosPtr - 1);
t1Ptr = valuePtr->typePtr;
t2Ptr = value2Ptr->typePtr;
@@ -3484,7 +3483,7 @@ TclExecuteByteCode(interp, codePtr)
double d;
Tcl_ObjType *tPtr;
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
tPtr = valuePtr->typePtr;
if (IS_INTEGER_TYPE(tPtr)
|| ((tPtr == &tclDoubleType) && (valuePtr->bytes == NULL))) {
@@ -3561,7 +3560,7 @@ TclExecuteByteCode(interp, codePtr)
int boolvar;
Tcl_ObjType *tPtr;
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
tPtr = valuePtr->typePtr;
if (IS_INTEGER_TYPE(tPtr)
|| ((tPtr == &tclDoubleType) && (valuePtr->bytes == NULL))) {
@@ -3679,7 +3678,7 @@ TclExecuteByteCode(interp, codePtr)
Tcl_ObjType *tPtr;
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
tPtr = valuePtr->typePtr;
if (!IS_INTEGER_TYPE(tPtr)) {
REQUIRE_WIDE_OR_INT(result, valuePtr, i, w);
@@ -3745,7 +3744,7 @@ TclExecuteByteCode(interp, codePtr)
if (result != TCL_OK) {
goto checkForCatch;
}
- TRACE_WITH_OBJ(("%d => ", opnd), stackPtr[stackTop]);
+ TRACE_WITH_OBJ(("%d => ", opnd), *tosPtr);
}
NEXT_INST_F(2, 0, 0);
@@ -3762,14 +3761,14 @@ TclExecuteByteCode(interp, codePtr)
Tcl_Obj **objv; /* The array of arguments. The function
* name is objv[0]. */
- objv = &(stackPtr[stackTop - (objc-1)]); /* "objv[0]" */
+ objv = (tosPtr - (objc-1)); /* "objv[0]" */
DECACHE_STACK_INFO();
result = ExprCallMathFunc(interp, eePtr, objc, objv);
CACHE_STACK_INFO();
if (result != TCL_OK) {
goto checkForCatch;
}
- TRACE_WITH_OBJ(("%d => ", objc), stackPtr[stackTop]);
+ TRACE_WITH_OBJ(("%d => ", objc), *tosPtr);
}
NEXT_INST_F(2, 0, 0);
@@ -3787,7 +3786,7 @@ TclExecuteByteCode(interp, codePtr)
Tcl_ObjType *tPtr;
int converted, needNew;
- valuePtr = stackPtr[stackTop];
+ valuePtr = *tosPtr;
tPtr = valuePtr->typePtr;
converted = 0;
if (IS_INTEGER_TYPE(tPtr)
@@ -4084,9 +4083,9 @@ TclExecuteByteCode(interp, codePtr)
* equal to the operand. Push the current stack depth onto the
* special catch stack.
*/
- catchStackPtr[++catchTop] = stackTop;
+ catchStackPtr[++catchTop] = (tosPtr - eePtr->stackPtr);
TRACE(("%u => catchTop=%d, stackTop=%d\n",
- TclGetUInt4AtPtr(pc+1), catchTop, stackTop));
+ TclGetUInt4AtPtr(pc+1), catchTop, tosPtr - eePtr->stackPtr));
NEXT_INST_F(5, 0, 0);
case INST_END_CATCH:
@@ -4171,7 +4170,7 @@ TclExecuteByteCode(interp, codePtr)
* before doing the cleanup.
*/
- TRACE(("\"%.30s\" => ", O2S(stackPtr[stackTop])));
+ TRACE(("\"%.30s\" => ", O2S(*tosPtr)));
break;
default:
TRACE(("=> "));
@@ -4279,7 +4278,7 @@ TclExecuteByteCode(interp, codePtr)
*/
processCatch:
- while (stackTop > catchStackPtr[catchTop]) {
+ while (tosPtr > catchStackPtr[catchTop] + eePtr->stackPtr) {
valuePtr = POP_OBJECT();
TclDecrRefCount(valuePtr);
}
@@ -4303,26 +4302,26 @@ TclExecuteByteCode(interp, codePtr)
*/
abnormalReturn:
- while (stackTop > initStackTop) {
- valuePtr = POP_OBJECT();
- TclDecrRefCount(valuePtr);
- }
- if (stackTop < initStackTop) {
- fprintf(stderr, "\nTclExecuteByteCode: abnormal return at pc %u: stack top %d < entry stack top %d\n",
- (unsigned int)(pc - codePtr->codeStart),
- (unsigned int) stackTop,
- (unsigned int) initStackTop);
- panic("TclExecuteByteCode execution failure: end stack top < start stack top");
+ {
+ Tcl_Obj **initTosPtr = eePtr->stackPtr + initStackTop;
+ while (tosPtr > initTosPtr) {
+ valuePtr = POP_OBJECT();
+ TclDecrRefCount(valuePtr);
+ }
+ if (tosPtr < initTosPtr) {
+ fprintf(stderr, "\nTclExecuteByteCode: abnormal return at pc %u: stack top %d < entry stack top %d\n",
+ (unsigned int)(pc - codePtr->codeStart),
+ (unsigned int) (tosPtr - eePtr->stackPtr),
+ (unsigned int) initStackTop);
+ panic("TclExecuteByteCode execution failure: end stack top < start stack top");
+ }
}
/*
* Free the catch stack array if malloc'ed storage was used.
*/
-
- if (catchStackPtr != catchStackStorage) {
- ckfree((char *) catchStackPtr);
- }
- eePtr->stackTop = initStackTop;
+
+ eePtr->tosPtr = (Tcl_Obj **) (catchStackPtr - 1);
return result;
#undef STATIC_CATCH_STACK_SIZE
}
@@ -4908,8 +4907,7 @@ ExprUnaryFunc(interp, eePtr, clientData)
* takes one double argument and returns a
* double result. */
{
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
register Tcl_Obj *valuePtr;
double d, dResult;
int result;
@@ -4972,8 +4970,7 @@ ExprBinaryFunc(interp, eePtr, clientData)
* takes two double arguments and
* returns a double result. */
{
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
register Tcl_Obj *valuePtr, *value2Ptr;
double d1, d2, dResult;
int result;
@@ -5038,8 +5035,7 @@ ExprAbsFunc(interp, eePtr, clientData)
* the function. */
ClientData clientData; /* Ignored. */
{
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
register Tcl_Obj *valuePtr;
long i, iResult;
double d, dResult;
@@ -5134,8 +5130,7 @@ ExprDoubleFunc(interp, eePtr, clientData)
* the function. */
ClientData clientData; /* Ignored. */
{
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
register Tcl_Obj *valuePtr;
double dResult;
int result;
@@ -5184,8 +5179,7 @@ ExprIntFunc(interp, eePtr, clientData)
* the function. */
ClientData clientData; /* Ignored. */
{
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
register Tcl_Obj *valuePtr;
long iResult;
double d;
@@ -5263,8 +5257,7 @@ ExprWideFunc(interp, eePtr, clientData)
* the function. */
ClientData clientData; /* Ignored. */
{
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
register Tcl_Obj *valuePtr;
Tcl_WideInt wResult;
double d;
@@ -5342,8 +5335,7 @@ ExprRandFunc(interp, eePtr, clientData)
* the function. */
ClientData clientData; /* Ignored. */
{
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
Interp *iPtr = (Interp *) interp;
double dResult;
long tmp; /* Algorithm assumes at least 32 bits.
@@ -5443,8 +5435,7 @@ ExprRoundFunc(interp, eePtr, clientData)
* the function. */
ClientData clientData; /* Ignored. */
{
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
Tcl_Obj *valuePtr;
long iResult;
double d, temp;
@@ -5528,8 +5519,7 @@ ExprSrandFunc(interp, eePtr, clientData)
* the function. */
ClientData clientData; /* Ignored. */
{
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
Interp *iPtr = (Interp *) interp;
Tcl_Obj *valuePtr;
long i = 0; /* Initialized to avoid compiler warning. */
@@ -5627,8 +5617,7 @@ ExprCallMathFunc(interp, eePtr, objc, objv)
* is objv[0]. */
{
Interp *iPtr = (Interp *) interp;
- Tcl_Obj **stackPtr; /* Cached evaluation stack base pointer. */
- register int stackTop; /* Cached top index of evaluation stack. */
+ register Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation stack. */
char *funcName;
Tcl_HashEntry *hPtr;
MathFunc *mathFuncPtr; /* Information about math function. */
@@ -5740,8 +5729,7 @@ ExprCallMathFunc(interp, eePtr, objc, objv)
* Pop the objc top stack elements and decrement their ref counts.
*/
- k = (stackTop - (objc-1));
- while (stackTop >= k) {
+ for (k = 0; k < objc; k++) {
valuePtr = POP_OBJECT();
TclDecrRefCount(valuePtr);
}
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 0da497b..2be3ad1 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclInt.h,v 1.131 2003/08/11 13:26:13 dkf Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.132 2003/09/23 14:48:49 msofer Exp $
*/
#ifndef _TCLINT
@@ -873,9 +873,9 @@ typedef int (CompileHookProc) _ANSI_ARGS_((Tcl_Interp *interp,
typedef struct ExecEnv {
Tcl_Obj **stackPtr; /* Points to the first item in the
* evaluation stack on the heap. */
- int stackTop; /* Index of current top of stack; -1 when
- * the stack is empty. */
- int stackEnd; /* Index of last usable item in stack. */
+ Tcl_Obj **tosPtr; /* Points to current top of stack;
+ * (stackPtr-1) when the stack is empty. */
+ Tcl_Obj **endPtr; /* Points to last usable item in stack. */
Tcl_Obj *errorInfo;
Tcl_Obj *errorCode;
} ExecEnv;