Tcl Source Code

Artifact [226f5747e9]
Login

Artifact 226f5747e9c1a27c53266eff7107749cb30643a4:

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);
 
 	/*