Attachment "1869989.patch" to
ticket [1869989fff]
added by
dgp
2008-01-17 02:11:23.
Index: generic/tclCompExpr.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCompExpr.c,v
retrieving revision 1.91
diff -u -r1.91 tclCompExpr.c
--- generic/tclCompExpr.c 15 Jan 2008 11:59:27 -0000 1.91
+++ generic/tclCompExpr.c 16 Jan 2008 19:08:46 -0000
@@ -833,47 +833,13 @@
switch (lexeme) {
case NUMBER:
- case BOOLEAN: {
- if (interp) {
- int new;
- /* LiteralEntry *lePtr; */
- Tcl_Obj *objPtr = TclCreateLiteral((Interp *)interp,
- (char *)start, scanned,
- /* hash */ (unsigned int) -1, &new,
- /* nsPtr */ NULL, /* flags */ 0,
- NULL /* &lePtr */);
- if (objPtr->typePtr != literal->typePtr) {
- /*
- * What we would like to do is this:
- *
- * lePtr->objPtr = literal;
- * Tcl_IncrRefCount(literal);
- * Tcl_DecrRefCount(objPtr);
- *
- * However, the design of the "global" and "local"
- * LiteralTable does not permit the value of
- * lePtr->objPtr to be changed. So rather than
- * replace lePtr->objPtr, we do surgery to transfer
- * the intrep of literal into it. Ugly stuff here
- * that's generally unsafe, but ok here since we know
- * the Tcl_ObjTypes literal might possibly have.
- */
- Tcl_Obj *toFree = literal;
- literal = objPtr;
- TclFreeIntRep(literal);
- literal->typePtr = toFree->typePtr;
- literal->internalRep = toFree->internalRep;
- toFree->typePtr = NULL;
- Tcl_DecrRefCount(toFree);
- }
- }
-
+ case BOOLEAN:
Tcl_ListObjAppendElement(NULL, litList, literal);
complete = lastParsed = OT_LITERAL;
start += scanned;
numBytes -= scanned;
continue;
- }
+
default:
break;
}
@@ -2345,10 +2311,25 @@
case OT_LITERAL: {
Tcl_Obj *const *litObjv = *litObjvPtr;
Tcl_Obj *literal = *litObjv;
- int length;
- const char *bytes = TclGetStringFromObj(literal, &length);
- TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, length), envPtr);
+ if (optimize) {
+ int length;
+ const char *bytes = TclGetStringFromObj(literal, &length);
+
+ /* TODO: Consider ways to preserve intrep */
+ TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, length),
+ envPtr);
+ } else {
+ /*
+ * When optimize==0, we know the expression is a one-off
+ * and there's nothing to be gained from sharing literals
+ * when they won't live long, and the copies we have already
+ * have an appropriate intrep. In this case, skip literal
+ * registration that would enable sharing, and use the routine
+ * that preserves intreps.
+ */
+ TclEmitPush(TclAddLiteralObj(envPtr, literal, NULL), envPtr);
+ }
(*litObjvPtr)++;
break;
}
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.358
diff -u -r1.358 tclExecute.c
--- generic/tclExecute.c 17 Dec 2007 15:28:27 -0000 1.358
+++ generic/tclExecute.c 16 Jan 2008 19:08:46 -0000
@@ -1228,6 +1228,13 @@
const char *string = TclGetStringFromObj(objPtr, &length);
TclInitCompileEnv(interp, &compEnv, string, length, NULL, 0);
+
+ /*
+ * TODO: Consider creating and calling an alternative routine
+ * that will compile bytecode for one-off expressions like this
+ * one with optimize==0, for improved efficiency.
+ */
+
TclCompileExpr(interp, string, length, &compEnv);
/*