summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2011-05-09 13:58:40 (GMT)
committerdgp <dgp@users.sourceforge.net>2011-05-09 13:58:40 (GMT)
commitd15ccfa119985df6db333ac406e1f445d5b6d89f (patch)
tree40679da226a994b460dd6ebf59379a3dd97a1241 /generic
parent8a15407fcc66e89fab893e964d8ad44fd98f55b7 (diff)
parenta4456778c8605e05c3598b6848b2660ae7b10d27 (diff)
downloadtcl-d15ccfa119985df6db333ac406e1f445d5b6d89f.zip
tcl-d15ccfa119985df6db333ac406e1f445d5b6d89f.tar.gz
tcl-d15ccfa119985df6db333ac406e1f445d5b6d89f.tar.bz2
Revise empty string tests so that we avoid potentially expensive string rep
generations, especially for dicts.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclListObj.c72
1 files changed, 11 insertions, 61 deletions
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index 28b86ec..a5f690e 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -459,24 +459,13 @@ Tcl_ListObjGetElements(
register List *listRepPtr;
if (listPtr->typePtr != &tclListType) {
- int result, length;
+ int result;
- /*
- * Don't get the string version of a dictionary; that transformation
- * is not lossy, but is expensive.
- */
-
- if (listPtr->typePtr == &tclDictType) {
- (void) Tcl_DictObjSize(NULL, listPtr, &length);
- } else {
- (void) TclGetStringFromObj(listPtr, &length);
- }
- if (!length) {
+ if (listPtr->bytes == tclEmptyStringRep) {
*objcPtr = 0;
*objvPtr = NULL;
return TCL_OK;
}
-
result = SetListFromAny(interp, listPtr);
if (result != TCL_OK) {
return result;
@@ -586,18 +575,12 @@ Tcl_ListObjAppendElement(
Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement");
}
if (listPtr->typePtr != &tclListType) {
- int result, length;
+ int result;
- if (listPtr->typePtr == &tclDictType) {
- (void) Tcl_DictObjSize(NULL, listPtr, &length);
- } else {
- (void) TclGetStringFromObj(listPtr, &length);
- }
- if (!length) {
+ if (listPtr->bytes == tclEmptyStringRep) {
Tcl_SetListObj(listPtr, 1, &objPtr);
return TCL_OK;
}
-
result = SetListFromAny(interp, listPtr);
if (result != TCL_OK) {
return result;
@@ -700,18 +683,12 @@ Tcl_ListObjIndex(
register List *listRepPtr;
if (listPtr->typePtr != &tclListType) {
- int result, length;
+ int result;
- if (listPtr->typePtr == &tclDictType) {
- (void) Tcl_DictObjSize(NULL, listPtr, &length);
- } else {
- (void) TclGetStringFromObj(listPtr, &length);
- }
- if (!length) {
+ if (listPtr->bytes == tclEmptyStringRep) {
*objPtrPtr = NULL;
return TCL_OK;
}
-
result = SetListFromAny(interp, listPtr);
if (result != TCL_OK) {
return result;
@@ -759,27 +736,12 @@ Tcl_ListObjLength(
register List *listRepPtr;
if (listPtr->typePtr != &tclListType) {
- int result, length;
+ int result;
- if (listPtr->typePtr == &tclDictType) {
- (void) Tcl_DictObjSize(NULL, listPtr, &length);
- /*
- * It's tempting to just report 2*length as the list length
- * of this dict, but arguably that's false since the max sizes
- * for dicts and lists are not the same, so some dicts don't
- * actually convert to lists, and it's good to get that error
- * back from the SetListFromAny() call below instead of a false
- * indication we can treat the value as a list. ([llength $val]
- * often used as a "listiness" test)
- */
- } else {
- (void) TclGetStringFromObj(listPtr, &length);
- }
- if (!length) {
+ if (listPtr->bytes == tclEmptyStringRep) {
*intPtr = 0;
return TCL_OK;
}
-
result = SetListFromAny(interp, listPtr);
if (result != TCL_OK) {
return result;
@@ -847,14 +809,7 @@ Tcl_ListObjReplace(
Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace");
}
if (listPtr->typePtr != &tclListType) {
- int length;
-
- if (listPtr->typePtr == &tclDictType) {
- (void) Tcl_DictObjSize(NULL, listPtr, &length);
- } else {
- (void) TclGetStringFromObj(listPtr, &length);
- }
- if (!length) {
+ if (listPtr->bytes == tclEmptyStringRep) {
if (objc) {
Tcl_SetListObj(listPtr, objc, NULL);
} else {
@@ -1570,14 +1525,9 @@ TclListObjSetElement(
Tcl_Panic("%s called with shared object", "TclListObjSetElement");
}
if (listPtr->typePtr != &tclListType) {
- int length, result;
+ int result;
- if (listPtr->typePtr == &tclDictType) {
- (void) Tcl_DictObjSize(NULL, listPtr, &length);
- } else {
- (void) TclGetStringFromObj(listPtr, &length);
- }
- if (!length) {
+ if (listPtr->bytes == tclEmptyStringRep) {
if (interp != NULL) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("list index out of range", -1));