summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2002-06-13 19:47:57 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2002-06-13 19:47:57 (GMT)
commitb2df30e5adb45bbbbdd44e958348149397eaa2d0 (patch)
tree8cfdc93aae1c6480fa1294c2d765c12c2e2a5e3c /generic
parentbb8e30079bb427d90dc44175fea4fe66ccc9d4d7 (diff)
downloadtcl-b2df30e5adb45bbbbdd44e958348149397eaa2d0.zip
tcl-b2df30e5adb45bbbbdd44e958348149397eaa2d0.tar.gz
tcl-b2df30e5adb45bbbbdd44e958348149397eaa2d0.tar.bz2
consolidated opcodes in the bytecode engine, eliminating duplicated
code. Added the new (but pre-existent in tcl.h) possible flag bit TCL_TRACE_READS to Tcl_(Obj)?SetVar.*
Diffstat (limited to 'generic')
-rw-r--r--generic/tclExecute.c674
-rw-r--r--generic/tclVar.c30
2 files changed, 217 insertions, 487 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index cd92324..13b4bfd 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.61 2002/06/11 12:38:22 msofer Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.62 2002/06/13 19:47:58 msofer Exp $
*/
#include "tclInt.h"
@@ -1001,6 +1001,7 @@ TclExecuteByteCode(interp, codePtr)
* instructions and processCatch to
* process break, continue, and errors. */
int result = TCL_OK; /* Return code returned after execution. */
+ int storeFlags;
#ifdef TCL_COMPILE_DEBUG
int traceInstructions = (tclTraceExec == 3);
#endif
@@ -1507,21 +1508,42 @@ TclExecuteByteCode(interp, codePtr)
TRACE_WITH_OBJ(("%u => ", opnd), valuePtr);
ADJUST_PC(5);
+ case INST_LOAD_ARRAY_STK:
+ elemPtr = POP_OBJECT();
+ goto doLoadStk;
+
case INST_LOAD_STK:
case INST_LOAD_SCALAR_STK:
+ elemPtr = NULL;
+
+ doLoadStk:
objPtr = POP_OBJECT(); /* scalar / variable name */
DECACHE_STACK_INFO();
- valuePtr = Tcl_ObjGetVar2(interp, objPtr, NULL, TCL_LEAVE_ERR_MSG);
+ valuePtr = Tcl_ObjGetVar2(interp, objPtr, elemPtr, TCL_LEAVE_ERR_MSG);
CACHE_STACK_INFO();
if (valuePtr == NULL) {
- TRACE_WITH_OBJ(("\"%.30s\" => ERROR: ", O2S(objPtr)),
- Tcl_GetObjResult(interp));
+ if (elemPtr != NULL) {
+ TRACE_WITH_OBJ(("\"%.30s(%.30s)\" => ERROR: ",
+ O2S(objPtr), O2S(elemPtr)),
+ Tcl_GetObjResult(interp));
+ TclDecrRefCount(elemPtr);
+
+ } else {
+ TRACE_WITH_OBJ(("\"%.30s\" => ERROR: ", O2S(objPtr)),
+ Tcl_GetObjResult(interp));
+ }
TclDecrRefCount(objPtr);
result = TCL_ERROR;
goto checkForCatch;
}
PUSH_OBJECT(valuePtr);
- TRACE_WITH_OBJ(("\"%.30s\" => ", O2S(objPtr)), valuePtr);
+ if (elemPtr != NULL) {
+ TRACE_WITH_OBJ(("\"%.30s(%.30s)\" => ",
+ O2S(objPtr), O2S(elemPtr)), valuePtr);
+ TclDecrRefCount(elemPtr);
+ } else {
+ TRACE_WITH_OBJ(("\"%.30s\" => ", O2S(objPtr)), valuePtr);
+ }
TclDecrRefCount(objPtr);
ADJUST_PC(1);
@@ -1554,158 +1576,46 @@ TclExecuteByteCode(interp, codePtr)
TclDecrRefCount(elemPtr);
ADJUST_PC(pcAdjustment);
- case INST_LOAD_ARRAY_STK:
- elemPtr = POP_OBJECT();
- objPtr = POP_OBJECT(); /* array name */
- DECACHE_STACK_INFO();
- valuePtr = Tcl_ObjGetVar2(interp, objPtr, elemPtr,
- TCL_LEAVE_ERR_MSG);
- CACHE_STACK_INFO();
- if (valuePtr == NULL) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" => ERROR: ",
- O2S(objPtr), O2S(elemPtr)),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(objPtr);
- TclDecrRefCount(elemPtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(valuePtr);
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" => ",
- O2S(objPtr), O2S(elemPtr)), valuePtr);
- TclDecrRefCount(objPtr);
- TclDecrRefCount(elemPtr);
- ADJUST_PC(1);
-
- case INST_STORE_SCALAR4:
+ case INST_LAPPEND_SCALAR4:
opnd = TclGetUInt4AtPtr(pc+1);
pcAdjustment = 5;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_TRACE_READS);
goto doStoreScalar;
- case INST_STORE_SCALAR1:
+ case INST_LAPPEND_SCALAR1:
opnd = TclGetUInt1AtPtr(pc+1);
- pcAdjustment = 2;
-
- doStoreScalar:
- valuePtr = POP_OBJECT();
- DECACHE_STACK_INFO();
- value2Ptr = TclSetIndexedScalar(interp, opnd, valuePtr,
- TCL_LEAVE_ERR_MSG);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("%u <- \"%.30s\" => ERROR: ",
- opnd, O2S(valuePtr)), Tcl_GetObjResult(interp));
- TclDecrRefCount(valuePtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("%u <- \"%.30s\" => ",
- opnd, O2S(valuePtr)), value2Ptr);
- TclDecrRefCount(valuePtr);
- ADJUST_PC(pcAdjustment);
-
- case INST_STORE_STK:
- case INST_STORE_SCALAR_STK:
- valuePtr = POP_OBJECT();
- objPtr = POP_OBJECT(); /* scalar / variable name */
- DECACHE_STACK_INFO();
- value2Ptr = Tcl_ObjSetVar2(interp, objPtr, NULL, valuePtr,
- TCL_LEAVE_ERR_MSG);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("\"%.30s\" <- \"%.30s\" => ERROR: ",
- O2S(objPtr), O2S(valuePtr)),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(objPtr);
- TclDecrRefCount(valuePtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("\"%.30s\" <- \"%.30s\" => ",
- O2S(objPtr), O2S(valuePtr)), value2Ptr);
- TclDecrRefCount(objPtr);
- TclDecrRefCount(valuePtr);
- ADJUST_PC(1);
+ pcAdjustment = 2;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_TRACE_READS);
+ goto doStoreScalar;
- case INST_STORE_ARRAY4:
+ case INST_APPEND_SCALAR4:
opnd = TclGetUInt4AtPtr(pc+1);
pcAdjustment = 5;
- goto doStoreArray;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+ goto doStoreScalar;
- case INST_STORE_ARRAY1:
+ case INST_APPEND_SCALAR1:
opnd = TclGetUInt1AtPtr(pc+1);
- pcAdjustment = 2;
-
- doStoreArray:
- valuePtr = POP_OBJECT();
- elemPtr = POP_OBJECT();
- DECACHE_STACK_INFO();
- value2Ptr = TclSetElementOfIndexedArray(interp, opnd,
- elemPtr, valuePtr, TCL_LEAVE_ERR_MSG);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("%u \"%.30s\" <- \"%.30s\" => ERROR: ",
- opnd, O2S(elemPtr), O2S(valuePtr)),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("%u \"%.30s\" <- \"%.30s\" => ",
- opnd, O2S(elemPtr), O2S(valuePtr)), value2Ptr);
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- ADJUST_PC(pcAdjustment);
-
- case INST_STORE_ARRAY_STK:
- valuePtr = POP_OBJECT();
- elemPtr = POP_OBJECT();
- objPtr = POP_OBJECT(); /* array name */
- DECACHE_STACK_INFO();
- value2Ptr = Tcl_ObjSetVar2(interp, objPtr, elemPtr, valuePtr,
- TCL_LEAVE_ERR_MSG);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <- \"%.30s\" => ERROR: ",
- O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(objPtr);
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <- \"%.30s\" => ",
- O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
- value2Ptr);
- TclDecrRefCount(objPtr);
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- ADJUST_PC(1);
-
- /*
- * START APPEND INSTRUCTIONS
- */
+ pcAdjustment = 2;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+ goto doStoreScalar;
- case INST_APPEND_SCALAR4:
+ case INST_STORE_SCALAR4:
opnd = TclGetUInt4AtPtr(pc+1);
pcAdjustment = 5;
- goto doAppendScalar;
+ storeFlags = TCL_LEAVE_ERR_MSG;
+ goto doStoreScalar;
- case INST_APPEND_SCALAR1:
+ case INST_STORE_SCALAR1:
opnd = TclGetUInt1AtPtr(pc+1);
pcAdjustment = 2;
+ storeFlags = TCL_LEAVE_ERR_MSG;
- doAppendScalar:
+ doStoreScalar:
valuePtr = POP_OBJECT();
DECACHE_STACK_INFO();
value2Ptr = TclSetIndexedScalar(interp, opnd, valuePtr,
- TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+ storeFlags);
CACHE_STACK_INFO();
if (value2Ptr == NULL) {
TRACE_WITH_OBJ(("%u <- \"%.30s\" => ERROR: ",
@@ -1720,29 +1630,57 @@ TclExecuteByteCode(interp, codePtr)
TclDecrRefCount(valuePtr);
ADJUST_PC(pcAdjustment);
+ case INST_LAPPEND_STK:
+ valuePtr = POP_OBJECT(); /* value to append */
+ elemPtr = NULL;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_TRACE_READS);
+ goto doStoreStk;
+
+ case INST_LAPPEND_ARRAY_STK:
+ valuePtr = POP_OBJECT(); /* value to append */
+ elemPtr = POP_OBJECT();
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_TRACE_READS);
+ goto doStoreStk;
+
case INST_APPEND_STK:
+ valuePtr = POP_OBJECT(); /* value to append */
+ elemPtr = NULL;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+ goto doStoreStk;
+
case INST_APPEND_ARRAY_STK:
valuePtr = POP_OBJECT(); /* value to append */
- if (*pc == INST_APPEND_ARRAY_STK) {
- elemPtr = POP_OBJECT();
- } else {
- elemPtr = NULL;
- }
- objPtr = POP_OBJECT(); /* scalar name */
+ elemPtr = POP_OBJECT();
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+ goto doStoreStk;
+
+ case INST_STORE_ARRAY_STK:
+ valuePtr = POP_OBJECT();
+ elemPtr = POP_OBJECT();
+ storeFlags = TCL_LEAVE_ERR_MSG;
+ goto doStoreStk;
+ case INST_STORE_STK:
+ case INST_STORE_SCALAR_STK:
+ valuePtr = POP_OBJECT();
+ elemPtr = NULL;
+ storeFlags = TCL_LEAVE_ERR_MSG;
+
+ doStoreStk:
+ objPtr = POP_OBJECT(); /* scalar or array variable name */
DECACHE_STACK_INFO();
value2Ptr = Tcl_ObjSetVar2(interp, objPtr, elemPtr, valuePtr,
- TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+ storeFlags);
CACHE_STACK_INFO();
if (value2Ptr == NULL) {
- if (elemPtr) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <-+ \"%.30s\" => ERROR: ",
+ if (elemPtr != NULL) {
+ TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <- \"%.30s\" => ERROR: ",
O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
Tcl_GetObjResult(interp));
TclDecrRefCount(elemPtr);
} else {
- TRACE_WITH_OBJ(("\"%.30s\" <-+ \"%.30s\" => ERROR: ",
- O2S(objPtr), O2S(valuePtr)),
+ TRACE_WITH_OBJ(("\"%.30s\" <- \"%.30s\" => ERROR: ",
+ O2S(objPtr), O2S(valuePtr)),
Tcl_GetObjResult(interp));
}
TclDecrRefCount(objPtr);
@@ -1751,37 +1689,63 @@ TclExecuteByteCode(interp, codePtr)
goto checkForCatch;
}
PUSH_OBJECT(value2Ptr);
- if (elemPtr) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <-+ \"%.30s\" => ",
- O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
- value2Ptr);
+ if (elemPtr != NULL) {
+ TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <- \"%.30s\" => ",
+ O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
+ value2Ptr);
TclDecrRefCount(elemPtr);
} else {
- TRACE_WITH_OBJ(("\"%.30s\" <-+ \"%.30s\" => ",
- O2S(objPtr), O2S(valuePtr)), value2Ptr);
+ TRACE_WITH_OBJ(("\"%.30s\" <- \"%.30s\" => ",
+ O2S(objPtr), O2S(valuePtr)), value2Ptr);
}
TclDecrRefCount(objPtr);
TclDecrRefCount(valuePtr);
ADJUST_PC(1);
+ case INST_LAPPEND_ARRAY4:
+ opnd = TclGetUInt4AtPtr(pc+1);
+ pcAdjustment = 5;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_TRACE_READS);
+ goto doStoreArray;
+
+ case INST_LAPPEND_ARRAY1:
+ opnd = TclGetUInt1AtPtr(pc+1);
+ pcAdjustment = 2;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_TRACE_READS);
+ goto doStoreArray;
+
case INST_APPEND_ARRAY4:
opnd = TclGetUInt4AtPtr(pc+1);
pcAdjustment = 5;
- goto doAppendArray;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+ goto doStoreArray;
case INST_APPEND_ARRAY1:
opnd = TclGetUInt1AtPtr(pc+1);
pcAdjustment = 2;
+ storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+ goto doStoreArray;
- doAppendArray:
+ case INST_STORE_ARRAY4:
+ opnd = TclGetUInt4AtPtr(pc+1);
+ pcAdjustment = 5;
+ storeFlags = TCL_LEAVE_ERR_MSG;
+ goto doStoreArray;
+
+ case INST_STORE_ARRAY1:
+ opnd = TclGetUInt1AtPtr(pc+1);
+ pcAdjustment = 2;
+ storeFlags = TCL_LEAVE_ERR_MSG;
+
+ doStoreArray:
valuePtr = POP_OBJECT();
elemPtr = POP_OBJECT();
DECACHE_STACK_INFO();
value2Ptr = TclSetElementOfIndexedArray(interp, opnd,
- elemPtr, valuePtr, TCL_LEAVE_ERR_MSG|TCL_APPEND_VALUE);
+ elemPtr, valuePtr, storeFlags);
CACHE_STACK_INFO();
if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("%u \"%.30s\" <-+ \"%.30s\" => ERROR: ",
+ TRACE_WITH_OBJ(("%u \"%.30s\" <- \"%.30s\" => ERROR: ",
opnd, O2S(elemPtr), O2S(valuePtr)),
Tcl_GetObjResult(interp));
TclDecrRefCount(elemPtr);
@@ -1790,16 +1754,12 @@ TclExecuteByteCode(interp, codePtr)
goto checkForCatch;
}
PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("%u \"%.30s\" <-+ \"%.30s\" => ",
+ TRACE_WITH_OBJ(("%u \"%.30s\" <- \"%.30s\" => ",
opnd, O2S(elemPtr), O2S(valuePtr)), value2Ptr);
TclDecrRefCount(elemPtr);
TclDecrRefCount(valuePtr);
ADJUST_PC(pcAdjustment);
- /*
- * END APPEND INSTRUCTIONS
- */
-
case INST_LIST:
/*
* Pop the opnd (objc) top stack elements into a new list obj
@@ -1816,172 +1776,6 @@ TclExecuteByteCode(interp, codePtr)
TRACE_WITH_OBJ(("%u => ", opnd), valuePtr);
ADJUST_PC(5);
- /*
- * START LAPPEND INSTRUCTIONS
- */
-
- case INST_LAPPEND_SCALAR4:
- opnd = TclGetUInt4AtPtr(pc+1);
- pcAdjustment = 5;
- goto doLappendScalar;
-
- case INST_LAPPEND_SCALAR1:
- opnd = TclGetUInt1AtPtr(pc+1);
- pcAdjustment = 2;
-
- doLappendScalar:
- valuePtr = POP_OBJECT();
- DECACHE_STACK_INFO();
- value2Ptr = TclSetIndexedScalar(interp, opnd, valuePtr,
- TCL_LEAVE_ERR_MSG|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("%u <- \"%.30s\" => ERROR: ",
- opnd, O2S(valuePtr)), Tcl_GetObjResult(interp));
- TclDecrRefCount(valuePtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("%u <- \"%.30s\" => ",
- opnd, O2S(valuePtr)), value2Ptr);
- TclDecrRefCount(valuePtr);
- ADJUST_PC(pcAdjustment);
-
- case INST_LAPPEND_STK:
- case INST_LAPPEND_ARRAY_STK:
- {
- /*
- * This compile function for this should be refactored
- * to make better use of existing LOAD/STORE instructions.
- */
- Tcl_Obj *newValuePtr;
- int createdNewObj = 0;
-
- value2Ptr = POP_OBJECT(); /* value to append */
- if (*pc == INST_LAPPEND_ARRAY_STK) {
- elemPtr = POP_OBJECT();
- } else {
- elemPtr = NULL;
- }
- objPtr = POP_OBJECT(); /* scalar name */
-
- DECACHE_STACK_INFO();
- /*
- * Currently value of the list.
- * Use the TCL_TRACE_READS flag to ensure that if we have an
- * array with no elements set yet, but with a read trace on it,
- * we will create the variable and get read traces triggered.
- */
- valuePtr = Tcl_ObjGetVar2(interp, objPtr, elemPtr,
- TCL_TRACE_READS);
- CACHE_STACK_INFO();
- if (valuePtr == NULL) {
- TclNewObj(valuePtr);
- createdNewObj = 1;
- } else if (Tcl_IsShared(valuePtr)) {
- valuePtr = Tcl_DuplicateObj(valuePtr);
- createdNewObj = 1;
- }
-
- DECACHE_STACK_INFO();
- result = Tcl_ListObjAppendElement(interp, valuePtr, value2Ptr);
- CACHE_STACK_INFO();
- if (result != TCL_OK) {
- if (elemPtr) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <- \"%.30s\" => ERROR: ",
- O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(elemPtr);
- } else {
- TRACE_WITH_OBJ(("\"%.30s\" <-+ \"%.30s\" => ERROR: ",
- O2S(objPtr), O2S(value2Ptr)),
- Tcl_GetObjResult(interp));
- }
- TclDecrRefCount(objPtr);
- TclDecrRefCount(value2Ptr);
- if (createdNewObj) {
- TclDecrRefCount(valuePtr);
- }
- result = TCL_ERROR;
- goto checkForCatch;
- }
-
- DECACHE_STACK_INFO();
- newValuePtr = Tcl_ObjSetVar2(interp, objPtr, elemPtr, valuePtr,
- TCL_LEAVE_ERR_MSG);
- CACHE_STACK_INFO();
- if (newValuePtr == NULL) {
- if (elemPtr) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <- \"%.30s\" => ERROR: ",
- O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(elemPtr);
- } else {
- TRACE_WITH_OBJ(("\"%.30s\" <-+ \"%.30s\" => ERROR: ",
- O2S(objPtr), O2S(value2Ptr)),
- Tcl_GetObjResult(interp));
- }
- TclDecrRefCount(objPtr);
- TclDecrRefCount(value2Ptr);
- if (createdNewObj) {
- TclDecrRefCount(valuePtr);
- }
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(newValuePtr);
- if (elemPtr) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <- \"%.30s\" => ",
- O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
- value2Ptr);
- TclDecrRefCount(elemPtr);
- } else {
- TRACE_WITH_OBJ(("\"%.30s\" <-+ \"%.30s\" => ",
- O2S(objPtr), O2S(valuePtr)), value2Ptr);
- }
- TclDecrRefCount(objPtr);
- TclDecrRefCount(value2Ptr);
- ADJUST_PC(1);
- }
-
- case INST_LAPPEND_ARRAY4:
- opnd = TclGetUInt4AtPtr(pc+1);
- pcAdjustment = 5;
- goto doLappendArray;
-
- case INST_LAPPEND_ARRAY1:
- opnd = TclGetUInt1AtPtr(pc+1);
- pcAdjustment = 2;
-
- doLappendArray:
- valuePtr = POP_OBJECT();
- elemPtr = POP_OBJECT();
- DECACHE_STACK_INFO();
- value2Ptr = TclSetElementOfIndexedArray(interp, opnd,
- elemPtr, valuePtr,
- TCL_LEAVE_ERR_MSG|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("%u \"%.30s\" <-+ \"%.30s\" => ERROR: ",
- opnd, O2S(elemPtr), O2S(valuePtr)),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("%u \"%.30s\" <-+ \"%.30s\" => ",
- opnd, O2S(elemPtr), O2S(valuePtr)), value2Ptr);
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- ADJUST_PC(pcAdjustment);
-
- /*
- * END (L)APPEND INSTRUCTIONS
- */
-
case INST_INCR_SCALAR1:
opnd = TclGetUInt1AtPtr(pc+1);
valuePtr = POP_OBJECT();
@@ -2001,25 +1795,39 @@ TclExecuteByteCode(interp, codePtr)
}
FORCE_LONG(valuePtr, i, w);
}
+ TclDecrRefCount(valuePtr);
+ pcAdjustment = 2;
+ goto doIncrScalarImm;
+
+ case INST_INCR_SCALAR1_IMM:
+ opnd = TclGetUInt1AtPtr(pc+1);
+ i = TclGetInt1AtPtr(pc+2);
+ pcAdjustment = 3;
+
+ doIncrScalarImm:
DECACHE_STACK_INFO();
value2Ptr = TclIncrIndexedScalar(interp, opnd, i);
CACHE_STACK_INFO();
if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("%u (by %ld) => ERROR: ", opnd, i),
+ TRACE_WITH_OBJ(("%u %ld => ERROR: ", opnd, i),
Tcl_GetObjResult(interp));
- TclDecrRefCount(valuePtr);
result = TCL_ERROR;
goto checkForCatch;
}
PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("%u (by %ld) => ", opnd, i), value2Ptr);
- TclDecrRefCount(valuePtr);
- ADJUST_PC(2);
+ TRACE_WITH_OBJ(("%u %ld => ", opnd, i), value2Ptr);
+ ADJUST_PC(pcAdjustment);
+
+ case INST_INCR_ARRAY_STK:
+ elemPtr = POP_OBJECT();
+ goto doIncrStkGetIncr;
case INST_INCR_SCALAR_STK:
case INST_INCR_STK:
+ elemPtr = NULL;
+
+ doIncrStkGetIncr:
valuePtr = POP_OBJECT();
- objPtr = POP_OBJECT(); /* scalar name */
if (valuePtr->typePtr == &tclIntType) {
i = valuePtr->internalRep.longValue;
#ifndef TCL_WIDE_INT_IS_LONG
@@ -2029,38 +1837,74 @@ TclExecuteByteCode(interp, codePtr)
} else {
REQUIRE_WIDE_OR_INT(result, valuePtr, i, w);
if (result != TCL_OK) {
- TRACE_WITH_OBJ(("\"%.30s\" (by %s) => ERROR converting increment amount to int: ",
- O2S(objPtr), O2S(valuePtr)),
- Tcl_GetObjResult(interp));
+ objPtr = POP_OBJECT(); /* scalar name */
+ if (elemPtr != NULL) {
+ TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %s) => ERROR converting increment amount to int: ",
+ O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
+ Tcl_GetObjResult(interp));
+ TclDecrRefCount(elemPtr);
+ } else {
+ TRACE_WITH_OBJ(("\"%.30s\" (by %s) => ERROR converting increment amount to int: ",
+ O2S(objPtr), O2S(valuePtr)),
+ Tcl_GetObjResult(interp));
+ }
TclDecrRefCount(objPtr);
TclDecrRefCount(valuePtr);
goto checkForCatch;
}
FORCE_LONG(valuePtr, i, w);
}
+ TclDecrRefCount(valuePtr);
+ pcAdjustment = 1;
+ goto doIncrStk;
+
+ case INST_INCR_ARRAY_STK_IMM:
+ elemPtr = POP_OBJECT();
+ goto doIncrStkImm;
+
+ case INST_INCR_SCALAR_STK_IMM:
+ case INST_INCR_STK_IMM:
+ elemPtr = NULL;
+
+ doIncrStkImm:
+ i = TclGetInt1AtPtr(pc+1);
+ pcAdjustment = 2;
+
+ doIncrStk:
+ objPtr = POP_OBJECT(); /* variable name */
DECACHE_STACK_INFO();
- value2Ptr = TclIncrVar2(interp, objPtr, (Tcl_Obj *) NULL, i,
+ value2Ptr = TclIncrVar2(interp, objPtr, elemPtr, i,
TCL_LEAVE_ERR_MSG);
CACHE_STACK_INFO();
if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("\"%.30s\" (by %ld) => ERROR: ",
- O2S(objPtr), i), Tcl_GetObjResult(interp));
- TclDecrRefCount(objPtr);
- TclDecrRefCount(valuePtr);
+ if (elemPtr != NULL) {
+ TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ERROR: ",
+ O2S(objPtr), O2S(elemPtr), i),
+ Tcl_GetObjResult(interp));
+ TclDecrRefCount(elemPtr);
+ } else {
+ TRACE_WITH_OBJ(("\"%.30s\" %ld => ERROR: ",
+ O2S(objPtr), i), Tcl_GetObjResult(interp));
+ }
result = TCL_ERROR;
+ TclDecrRefCount(objPtr);
goto checkForCatch;
}
PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("\"%.30s\" (by %ld) => ", O2S(objPtr), i),
- value2Ptr);
+ if (elemPtr != NULL) {
+ TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ",
+ O2S(objPtr), O2S(elemPtr), i), value2Ptr);
+ TclDecrRefCount(elemPtr);
+ } else {
+ TRACE_WITH_OBJ(("\"%.30s\" %ld => ", O2S(objPtr), i),
+ value2Ptr);
+ }
TclDecrRefCount(objPtr);
- TclDecrRefCount(valuePtr);
- ADJUST_PC(1);
+ ADJUST_PC(pcAdjustment);
case INST_INCR_ARRAY1:
opnd = TclGetUInt1AtPtr(pc+1);
valuePtr = POP_OBJECT();
- elemPtr = POP_OBJECT();
if (valuePtr->typePtr == &tclIntType) {
i = valuePtr->internalRep.longValue;
#ifndef TCL_WIDE_INT_IS_LONG
@@ -2070,6 +1914,7 @@ TclExecuteByteCode(interp, codePtr)
} else {
REQUIRE_WIDE_OR_INT(result, valuePtr, i, w);
if (result != TCL_OK) {
+ elemPtr = POP_OBJECT();
TRACE_WITH_OBJ(("%u \"%.30s\" (by %s) => ERROR converting increment amount to int: ",
opnd, O2S(elemPtr), O2S(valuePtr)),
Tcl_GetObjResult(interp));
@@ -2079,111 +1924,16 @@ TclExecuteByteCode(interp, codePtr)
}
FORCE_LONG(valuePtr, i, w);
}
- DECACHE_STACK_INFO();
- value2Ptr = TclIncrElementOfIndexedArray(interp, opnd,
- elemPtr, i);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("%u \"%.30s\" (by %ld) => ERROR: ",
- opnd, O2S(elemPtr), i),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("%u \"%.30s\" (by %ld) => ",
- opnd, O2S(elemPtr), i), value2Ptr);
- TclDecrRefCount(elemPtr);
TclDecrRefCount(valuePtr);
- ADJUST_PC(2);
-
- case INST_INCR_ARRAY_STK:
- valuePtr = POP_OBJECT();
- elemPtr = POP_OBJECT();
- objPtr = POP_OBJECT(); /* array name */
- if (valuePtr->typePtr == &tclIntType) {
- i = valuePtr->internalRep.longValue;
-#ifndef TCL_WIDE_INT_IS_LONG
- } else if (valuePtr->typePtr == &tclWideIntType) {
- i = Tcl_WideAsLong(valuePtr->internalRep.wideValue);
-#endif /* TCL_WIDE_INT_IS_LONG */
- } else {
- REQUIRE_WIDE_OR_INT(result, valuePtr, i, w);
- if (result != TCL_OK) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %s) => ERROR converting increment amount to int: ",
- O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(objPtr);
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- goto checkForCatch;
- }
- FORCE_LONG(valuePtr, i, w);
- }
- DECACHE_STACK_INFO();
- value2Ptr = TclIncrVar2(interp, objPtr, elemPtr, i,
- TCL_LEAVE_ERR_MSG);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ERROR: ",
- O2S(objPtr), O2S(elemPtr), i),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(objPtr);
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ",
- O2S(objPtr), O2S(elemPtr), i), value2Ptr);
- TclDecrRefCount(objPtr);
- TclDecrRefCount(elemPtr);
- TclDecrRefCount(valuePtr);
- ADJUST_PC(1);
-
- case INST_INCR_SCALAR1_IMM:
- opnd = TclGetUInt1AtPtr(pc+1);
- i = TclGetInt1AtPtr(pc+2);
- DECACHE_STACK_INFO();
- value2Ptr = TclIncrIndexedScalar(interp, opnd, i);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("%u %ld => ERROR: ", opnd, i),
- Tcl_GetObjResult(interp));
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("%u %ld => ", opnd, i), value2Ptr);
- ADJUST_PC(3);
-
- case INST_INCR_SCALAR_STK_IMM:
- case INST_INCR_STK_IMM:
- objPtr = POP_OBJECT(); /* variable name */
- i = TclGetInt1AtPtr(pc+1);
- DECACHE_STACK_INFO();
- value2Ptr = TclIncrVar2(interp, objPtr, (Tcl_Obj *) NULL, i,
- TCL_LEAVE_ERR_MSG);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("\"%.30s\" %ld => ERROR: ",
- O2S(objPtr), i), Tcl_GetObjResult(interp));
- result = TCL_ERROR;
- TclDecrRefCount(objPtr);
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("\"%.30s\" %ld => ", O2S(objPtr), i),
- value2Ptr);
- TclDecrRefCount(objPtr);
- ADJUST_PC(2);
+ pcAdjustment = 2;
+ goto doIncrArrayImm;
case INST_INCR_ARRAY1_IMM:
opnd = TclGetUInt1AtPtr(pc+1);
i = TclGetInt1AtPtr(pc+2);
+ pcAdjustment = 3;
+
+ doIncrArrayImm:
elemPtr = POP_OBJECT();
DECACHE_STACK_INFO();
value2Ptr = TclIncrElementOfIndexedArray(interp, opnd,
@@ -2201,32 +1951,8 @@ TclExecuteByteCode(interp, codePtr)
TRACE_WITH_OBJ(("%u \"%.30s\" (by %ld) => ",
opnd, O2S(elemPtr), i), value2Ptr);
TclDecrRefCount(elemPtr);
- ADJUST_PC(3);
-
- case INST_INCR_ARRAY_STK_IMM:
- i = TclGetInt1AtPtr(pc+1);
- elemPtr = POP_OBJECT();
- objPtr = POP_OBJECT(); /* array name */
- DECACHE_STACK_INFO();
- value2Ptr = TclIncrVar2(interp, objPtr, elemPtr, i,
- TCL_LEAVE_ERR_MSG);
- CACHE_STACK_INFO();
- if (value2Ptr == NULL) {
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ERROR: ",
- O2S(objPtr), O2S(elemPtr), i),
- Tcl_GetObjResult(interp));
- TclDecrRefCount(objPtr);
- TclDecrRefCount(elemPtr);
- result = TCL_ERROR;
- goto checkForCatch;
- }
- PUSH_OBJECT(value2Ptr);
- TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ",
- O2S(objPtr), O2S(elemPtr), i), value2Ptr);
- TclDecrRefCount(objPtr);
- TclDecrRefCount(elemPtr);
- ADJUST_PC(2);
-
+ ADJUST_PC(pcAdjustment);
+
/*
* END INCR INSTRUCTIONS
*/
diff --git a/generic/tclVar.c b/generic/tclVar.c
index 6857a9f..133b387 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -15,7 +15,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclVar.c,v 1.51 2002/03/29 00:02:42 dgp Exp $
+ * RCS: @(#) $Id: tclVar.c,v 1.52 2002/06/13 19:47:58 msofer Exp $
*/
#include "tclInt.h"
@@ -1243,12 +1243,18 @@ Tcl_SetVar2Ex(interp, part1, part2, newValuePtr, flags)
}
/*
- * At this point, if we were appending, we used to call read traces: we
- * treated append as a read-modify-write. However, it seemed unlikely to
- * us that a real program would be interested in such reads being done
- * during a set operation.
+ * Invoke any read traces that have been set for the variable if it
+ * is requested; this is only done in the core when lappending.
*/
+ if ((flags & TCL_TRACE_READS) && ((varPtr->tracePtr != NULL)
+ || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL)))) {
+ if (TCL_ERROR == CallTraces(iPtr, arrayPtr, varPtr, part1, part2,
+ TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG))) {
+ return NULL;
+ }
+ }
+
/*
* Set the variable's new value. If appending, append the new value to
* the variable, either as a list element or as a string. Also, if
@@ -1448,12 +1454,11 @@ TclSetIndexedScalar(interp, localIndex, newValuePtr, flags)
}
/*
- * Invoke any read traces that have been set for the variable if we
- * are appending, but only in the lappend case.
+ * Invoke any read traces that have been set for the variable if it
+ * is requested; this is only done in the core when lappending.
*/
- if ((flags & TCL_APPEND_VALUE) && (flags & TCL_LIST_ELEMENT)
- && (varPtr->tracePtr != NULL)) {
+ if ((flags & TCL_TRACE_READS) && (varPtr->tracePtr != NULL)) {
if (TCL_ERROR == CallTraces(iPtr, /*arrayPtr*/ NULL, varPtr, varName,
NULL, TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG))) {
return NULL;
@@ -1749,12 +1754,11 @@ TclSetElementOfIndexedArray(interp, localIndex, elemPtr, newValuePtr, flags)
}
/*
- * Invoke any read traces that have been set for the element variable if
- * we are appending, but only in the lappend case.
+ * Invoke any read traces that have been set for the variable if it
+ * is requested; this is only done in the core when lappending.
*/
- if ((flags & TCL_APPEND_VALUE) && (flags & TCL_LIST_ELEMENT)
- && ((varPtr->tracePtr != NULL)
+ if ((flags & TCL_TRACE_READS) && ((varPtr->tracePtr != NULL)
|| ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL)))) {
if (TCL_ERROR == CallTraces(iPtr, arrayPtr, varPtr, arrayName, elem,
TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG))) {