summaryrefslogtreecommitdiffstats
path: root/generic/tclConfig.c
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2005-04-02 02:08:22 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2005-04-02 02:08:22 (GMT)
commit95b50e96cfeca13080aa95e5a4cd378cbea25955 (patch)
tree60e127a56dc4b46c2944f5cd3e2270be9489cdca /generic/tclConfig.c
parentfbb5749d9fa84503a3480ab6e24a9f0436772110 (diff)
downloadtcl-95b50e96cfeca13080aa95e5a4cd378cbea25955.zip
tcl-95b50e96cfeca13080aa95e5a4cd378cbea25955.tar.gz
tcl-95b50e96cfeca13080aa95e5a4cd378cbea25955.tar.bz2
Changed the internal representation of lists to (a) reduce the malloc/free
calls at list creation (from 2 to 1), (b) reduce the cost of handling empty lists (we now never create a list internal rep for them), (c) allow refcounting of the list internal rep. The latter permits insuring that the pointers returned by Tcl_ListObjGetElements remain valid even if the object shimmers away from its original list type. This is [Patch 1158008]
Diffstat (limited to 'generic/tclConfig.c')
-rw-r--r--generic/tclConfig.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/generic/tclConfig.c b/generic/tclConfig.c
index 4daf92f..4172fdb 100644
--- a/generic/tclConfig.c
+++ b/generic/tclConfig.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclConfig.c,v 1.6 2004/10/29 15:39:05 dkf Exp $
+ * RCS: @(#) $Id: tclConfig.c,v 1.7 2005/04/02 02:08:32 msofer Exp $
*/
#include "tclInt.h"
@@ -196,7 +196,7 @@ QueryConfigObjCmd(clientData, interp, objc, objv)
struct Tcl_Obj * CONST *objv;
{
Tcl_Obj *pkgName = (Tcl_Obj*) clientData;
- Tcl_Obj *pDB, *pkgDict, *val;
+ Tcl_Obj *pDB, *pkgDict, *val, *listPtr;
Tcl_DictSearch s;
int n, i, res, done, index;
Tcl_Obj *key, **vals;
@@ -248,19 +248,29 @@ QueryConfigObjCmd(clientData, interp, objc, objv)
}
Tcl_DictObjSize(interp, pkgDict, &n);
- if (n == 0) {
- Tcl_SetObjResult(interp, Tcl_NewListObj(0, NULL));
- return TCL_OK;
+ listPtr = Tcl_NewListObj(n, NULL);
+
+ if (!listPtr) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("insufficient memory to create list", -1));
+ return TCL_ERROR;
}
-
- vals = (Tcl_Obj**) ckalloc(n * sizeof(Tcl_Obj*));
-
- for (i=0, Tcl_DictObjFirst(interp, pkgDict, &s, &key, NULL, &done);
- !done; Tcl_DictObjNext(&s, &key, NULL, &done), i++) {
- vals[i] = key;
+
+ if (n) {
+ List *listRepPtr =
+ (List *) listPtr->internalRep.twoPtrValue.ptr1;
+
+ listRepPtr->elemCount = n;
+ vals = &listRepPtr->elements;
+
+ for (i=0, Tcl_DictObjFirst(interp, pkgDict, &s, &key, NULL, &done);
+ !done; Tcl_DictObjNext(&s, &key, NULL, &done), i++) {
+ vals[i] = key;
+ Tcl_IncrRefCount(key);
+ }
}
- Tcl_SetObjResult(interp, TclNewListObjDirect(n, vals));
+ Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
default: