summaryrefslogtreecommitdiffstats
path: root/generic/tclCompExpr.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2007-08-24 21:34:19 (GMT)
committerdgp <dgp@users.sourceforge.net>2007-08-24 21:34:19 (GMT)
commitebc953ef5e8e0b2737ee370fce7d6198012b7ab9 (patch)
tree9ffa29cc44abc113e85de51d6c0b8266e0a51ca6 /generic/tclCompExpr.c
parentb6a2ba77d8842784d7c08493108d009ae42cae1b (diff)
downloadtcl-ebc953ef5e8e0b2737ee370fce7d6198012b7ab9.zip
tcl-ebc953ef5e8e0b2737ee370fce7d6198012b7ab9.tar.gz
tcl-ebc953ef5e8e0b2737ee370fce7d6198012b7ab9.tar.bz2
* generic/tclCompExpr.c: Register literals found in expressions
* tests/compExpr.test: to restore literal sharing. Preserve numeric intreps when literals are created for the first time. Correct memleak in ExecConstantExprTree() and add test for the leak.
Diffstat (limited to 'generic/tclCompExpr.c')
-rw-r--r--generic/tclCompExpr.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c
index 74e5528..942f82a 100644
--- a/generic/tclCompExpr.c
+++ b/generic/tclCompExpr.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCompExpr.c,v 1.79 2007/08/23 17:20:07 dgp Exp $
+ * RCS: @(#) $Id: tclCompExpr.c,v 1.80 2007/08/24 21:34:19 dgp Exp $
*/
#include "tclInt.h"
@@ -761,12 +761,27 @@ ParseExpr(
switch (lexeme) {
case NUMBER:
- case BOOLEAN:
+ 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, &lePtr);
+ if (new) {
+ lePtr->objPtr = literal;
+ Tcl_IncrRefCount(literal);
+ Tcl_DecrRefCount(objPtr);
+ }
+ }
+
Tcl_ListObjAppendElement(NULL, litList, literal);
complete = lastParsed = OT_LITERAL;
start += scanned;
numBytes -= scanned;
continue;
+ }
default:
break;
}
@@ -2067,6 +2082,9 @@ ExecConstantExprTree(
TclEmitOpcode(INST_DONE, envPtr);
Tcl_IncrRefCount(byteCodeObj);
TclInitByteCodeObj(byteCodeObj, envPtr);
+ if (envPtr->localLitTable.buckets != envPtr->localLitTable.staticBuckets) {
+ ckfree((char *) envPtr->localLitTable.buckets);
+ }
TclFreeCompileEnv(envPtr);
TclStackFree(interp, envPtr);
byteCodePtr = (ByteCode *) byteCodeObj->internalRep.otherValuePtr;
@@ -2293,10 +2311,16 @@ CompileExprTree(
case OT_EMPTY:
numWords = 1; /* No arguments, so just the command */
break;
- case OT_LITERAL:
- TclEmitPush(TclAddLiteralObj(envPtr, *(*litObjvPtr)++, NULL),
- envPtr);
+ case OT_LITERAL: {
+ Tcl_Obj *const *litObjv = *litObjvPtr;
+ Tcl_Obj *literal = *litObjv;
+ int length;
+ const char *bytes = Tcl_GetStringFromObj(literal, &length);
+
+ TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, length), envPtr);
+ (*litObjvPtr)++;
break;
+ }
case OT_TOKENS:
TclCompileTokens(interp, tokenPtr+1, tokenPtr->numComponents,
envPtr);