summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
authorhobbs <hobbs>1999-12-12 02:26:40 (GMT)
committerhobbs <hobbs>1999-12-12 02:26:40 (GMT)
commit9d5c1c3ab0220165e8761184bf18b03a0018c0e8 (patch)
treea0669e049fc8824bf3b37835e2244bac6c56a8d8 /generic/tclBasic.c
parent5f809539e37de57ab0461f54c17db348eac6e0dd (diff)
downloadtcl-9d5c1c3ab0220165e8761184bf18b03a0018c0e8.zip
tcl-9d5c1c3ab0220165e8761184bf18b03a0018c0e8.tar.gz
tcl-9d5c1c3ab0220165e8761184bf18b03a0018c0e8.tar.bz2
* tests/var.test:
* generic/tclCompile.c: fixed problem where setting to {} array would intermittently not work. (Fontaine) [Bug: 3339] * generic/tclCmdMZ.c: * generic/tclExecute.c: optimized INST_TRY_CVT_TO_NUMERIC to recognize boolean objects. (Spjuth) [Bug: 2815] * tests/info.test: * tests/parseOld.test: * generic/tclCmdAH.c: * generic/tclProc.c: changed Tcl_UplevelObjCmd (uplevel) and Tcl_EvalObjCmd (eval) to use TCL_EVAL_DIRECT in the single arg case as well, to take advantage of potential pure list input optimization. This means that it won't get byte compiled though, which should be acceptable. * generic/tclBasic.c: made Tcl_EvalObjEx pure list object aware in the TCL_EVAL_DIRECT case for efficiency. * generic/tclUtil.c: made Tcl_ConcatObj pure list object aware, and return a list object in that case [Bug: 2098 2257] * generic/tclMain.c: changed Tcl_Main to not constantly reuse the commandPtr object (interactive case) as it could be shared. (Fellows)
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 20b37dc..9691459 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclBasic.c,v 1.22 1999/11/19 06:34:22 hobbs Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.23 1999/12/12 02:26:40 hobbs Exp $
*/
#include "tclInt.h"
@@ -2495,7 +2495,8 @@ Tcl_CreateMathFunc(interp, name, numArgs, argTypes, proc, clientData)
* Tcl_EvalObjEx --
*
* Execute Tcl commands stored in a Tcl object. These commands are
- * compiled into bytecodes if necessary.
+ * compiled into bytecodes if necessary, unless TCL_EVAL_DIRECT
+ * is specified.
*
* Results:
* The return value is one of the return codes defined in tcl.h
@@ -2539,10 +2540,6 @@ Tcl_EvalObjEx(interp, objPtr, flags)
* in case TCL_EVAL_GLOBAL was set. */
Namespace *namespacePtr;
- /*
- * Prevent the object from being deleted as a side effect of evaling it.
- */
-
Tcl_IncrRefCount(objPtr);
if ((iPtr->flags & USE_EVAL_DIRECT) || (flags & TCL_EVAL_DIRECT)) {
@@ -2550,17 +2547,36 @@ Tcl_EvalObjEx(interp, objPtr, flags)
* We're not supposed to use the compiler or byte-code interpreter.
* Let Tcl_EvalEx evaluate the command directly (and probably
* more slowly).
+ *
+ * Pure List Optimization (no string representation). In this
+ * case, we can safely use Tcl_EvalObjv instead and get an
+ * appreciable improvement in execution speed. This is because it
+ * allows us to avoid a setFromAny step that would just pack
+ * everything into a string and back out again.
+ *
+ * USE_EVAL_DIRECT is a special flag used for testing purpose only
+ * (ensure we go into the TCL_EVAL_DIRECT path, avoiding opt)
*/
-
- char *p;
- int length;
-
- p = Tcl_GetStringFromObj(objPtr, &length);
- result = Tcl_EvalEx(interp, p, length, flags);
+ if (!(iPtr->flags & USE_EVAL_DIRECT) &&
+ (objPtr->typePtr == &tclListType) && /* is a list... */
+ (objPtr->bytes == NULL) /* ...without a string rep */) {
+ register List *listRepPtr =
+ (List *) objPtr->internalRep.otherValuePtr;
+ result = Tcl_EvalObjv(interp, listRepPtr->elemCount,
+ listRepPtr->elements, flags);
+ } else {
+ register char *p;
+ p = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
+ result = Tcl_EvalEx(interp, p, numSrcBytes, flags);
+ }
Tcl_DecrRefCount(objPtr);
return result;
}
+ /*
+ * Prevent the object from being deleted as a side effect of evaling it.
+ */
+
savedVarFramePtr = iPtr->varFramePtr;
if (flags & TCL_EVAL_GLOBAL) {
iPtr->varFramePtr = NULL;