summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--generic/tclBasic.c85
-rw-r--r--generic/tclInt.h6
-rw-r--r--generic/tclUtil.c17
4 files changed, 54 insertions, 60 deletions
diff --git a/ChangeLog b/ChangeLog
index c28b0d1..d9e54e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2011-04-18 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h: Define and use macros that test whether
+ * generic/tclBasic.c: a Tcl list value is canonical.
+ * generic/tclUtil.c:
+
2011-04-18 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tcl.h: fix for [Bug 3288345]: Wrong Tcl_StatBuf
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 596254d..71bd45c 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -4900,8 +4900,7 @@ TclArgumentGet(interp,obj,cfPtrPtr,wordPtr)
* up by the caller. It knows better than us.
*/
- if ((!obj->bytes) || ((obj->typePtr == &tclListType) &&
- ((List *)obj->internalRep.twoPtrValue.ptr1)->canonicalFlag)) {
+ if ((obj->bytes == NULL) || TclListObjIsCanonical(obj)) {
return;
}
@@ -5083,61 +5082,50 @@ TclEvalObjEx(
* internal rep).
*/
- if (objPtr->typePtr == &tclListType) { /* is a list... */
- List *listRepPtr = objPtr->internalRep.twoPtrValue.ptr1;
-
- if (objPtr->bytes == NULL || /* ...without a string rep */
- listRepPtr->canonicalFlag) {/* ...or that is canonical */
- /*
- * TIP #280 Structures for tracking lines. As we know that this is
- * dynamic execution we ignore the invoker, even if known.
- */
+ if (TclListObjIsCanonical(objPtr)) {
+ /*
+ * TIP #280 Structures for tracking lines. As we know that this is
+ * dynamic execution we ignore the invoker, even if known.
+ */
- int nelements;
- Tcl_Obj **elements, *copyPtr = TclListObjCopy(NULL, objPtr);
- CmdFrame *eoFramePtr = (CmdFrame *)
+ int nelements;
+ Tcl_Obj **elements, *copyPtr = TclListObjCopy(NULL, objPtr);
+ CmdFrame *eoFramePtr = (CmdFrame *)
TclStackAlloc(interp, sizeof(CmdFrame));
- eoFramePtr->type = TCL_LOCATION_EVAL_LIST;
- eoFramePtr->level = (iPtr->cmdFramePtr == NULL?
- 1 : iPtr->cmdFramePtr->level + 1);
- eoFramePtr->framePtr = iPtr->framePtr;
- eoFramePtr->nextPtr = iPtr->cmdFramePtr;
-
- eoFramePtr->nline = 0;
- eoFramePtr->line = NULL;
+ eoFramePtr->type = TCL_LOCATION_EVAL_LIST;
+ eoFramePtr->level = (iPtr->cmdFramePtr == NULL? 1
+ : iPtr->cmdFramePtr->level + 1);
+ eoFramePtr->framePtr = iPtr->framePtr;
+ eoFramePtr->nextPtr = iPtr->cmdFramePtr;
- eoFramePtr->cmd.listPtr = objPtr;
- Tcl_IncrRefCount(eoFramePtr->cmd.listPtr);
- eoFramePtr->data.eval.path = NULL;
+ eoFramePtr->nline = 0;
+ eoFramePtr->line = NULL;
- /*
- * 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.
- */
+ eoFramePtr->cmd.listPtr = objPtr;
+ Tcl_IncrRefCount(eoFramePtr->cmd.listPtr);
+ eoFramePtr->data.eval.path = NULL;
- Tcl_ListObjGetElements(NULL, copyPtr,
- &nelements, &elements);
+ /*
+ * 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.
+ */
- iPtr->cmdFramePtr = eoFramePtr;
- result = Tcl_EvalObjv(interp, nelements, elements,
- flags);
+ Tcl_ListObjGetElements(NULL, copyPtr, &nelements, &elements);
- Tcl_DecrRefCount(copyPtr);
- iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr;
- Tcl_DecrRefCount(eoFramePtr->cmd.listPtr);
- TclStackFree(interp, eoFramePtr);
+ iPtr->cmdFramePtr = eoFramePtr;
+ result = Tcl_EvalObjv(interp, nelements, elements, flags);
- goto done;
- }
- }
-
- if (flags & TCL_EVAL_DIRECT) {
+ Tcl_DecrRefCount(copyPtr);
+ iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr;
+ Tcl_DecrRefCount(eoFramePtr->cmd.listPtr);
+ TclStackFree(interp, eoFramePtr);
+ } else if (flags & TCL_EVAL_DIRECT) {
/*
* We're not supposed to use the compiler or byte-code interpreter.
* Let Tcl_EvalEx evaluate the command directly (and probably more
@@ -5297,7 +5285,6 @@ TclEvalObjEx(
iPtr->varFramePtr = savedVarFramePtr;
}
- done:
TclDecrRefCount(objPtr);
return result;
}
diff --git a/generic/tclInt.h b/generic/tclInt.h
index b8a4dfa..ca565dd 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2207,6 +2207,9 @@ typedef struct List {
#define ListObjLength(listPtr, len) \
((len) = ListRepPtr(listPtr)->elemCount)
+#define ListObjIsCanonical(listPtr) \
+ (((listPtr)->bytes == NULL) || ListRepPtr(listPtr)->canonicalFlag)
+
#define TclListObjGetElements(interp, listPtr, objcPtr, objvPtr) \
(((listPtr)->typePtr == &tclListType) \
? ((ListObjGetElements((listPtr), *(objcPtr), *(objvPtr))), TCL_OK)\
@@ -2217,6 +2220,9 @@ typedef struct List {
? ((ListObjLength((listPtr), *(lenPtr))), TCL_OK)\
: Tcl_ListObjLength((interp), (listPtr), (lenPtr)))
+#define TclListObjIsCanonical(listPtr) \
+ (((listPtr)->typePtr == &tclListType) ? ListObjIsCanonical((listPtr)) : 0)
+
/*
* Macros providing a faster path to integers: Tcl_GetLongFromObj everywhere,
* Tcl_GetIntFromObj and TclGetIntForIndex on platforms where longs are ints.
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 44a24f8..b3e1e08 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -1196,19 +1196,14 @@ Tcl_ConcatObj(
*/
for (i = 0; i < objc; i++) {
- List *listRepPtr;
+ int length;
objPtr = objv[i];
- if (objPtr->typePtr != &tclListType) {
- TclGetString(objPtr);
- if (objPtr->length) {
- break;
- } else {
- continue;
- }
+ if (TclListObjIsCanonical(objPtr)) {
+ continue;
}
- listRepPtr = (List *) objPtr->internalRep.twoPtrValue.ptr1;
- if (objPtr->bytes != NULL && !listRepPtr->canonicalFlag) {
+ Tcl_GetStringFromObj(objPtr, &length);
+ if (length > 0) {
break;
}
}
@@ -1228,7 +1223,7 @@ Tcl_ConcatObj(
*/
objPtr = objv[i];
- if (objPtr->bytes && !objPtr->length) {
+ if (objPtr->bytes && objPtr->length == 0) {
continue;
}
TclListObjGetElements(NULL, objPtr, &listc, &listv);