diff options
author | dgp <dgp@users.sourceforge.net> | 2011-05-09 13:58:40 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2011-05-09 13:58:40 (GMT) |
commit | d15ccfa119985df6db333ac406e1f445d5b6d89f (patch) | |
tree | 40679da226a994b460dd6ebf59379a3dd97a1241 /generic | |
parent | 8a15407fcc66e89fab893e964d8ad44fd98f55b7 (diff) | |
parent | a4456778c8605e05c3598b6848b2660ae7b10d27 (diff) | |
download | tcl-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.c | 72 |
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)); |