summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--generic/tclObj.c73
2 files changed, 35 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index 9d75fe7..302f890 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2007-06-09 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclObj.c (Tcl_GetCommandFromObj): rewritten to make the
+ logic clearer; slightly faster too.
+
* generic/tclBasic.c: Split TEOv in two, by separating a
processor for non-TCL_OK returns. Also spli TEOvI in a full
version that handles non-existing and traced commands, and a
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 36596c5..1c6384a 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.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: tclObj.c,v 1.123 2007/06/09 20:12:55 msofer Exp $
+ * RCS: @(#) $Id: tclObj.c,v 1.124 2007/06/09 21:07:31 msofer Exp $
*/
#include "tclInt.h"
@@ -3465,7 +3465,7 @@ Tcl_GetCommandFromObj(
register Command *cmdPtr;
Namespace *currNsPtr;
int result;
- CallFrame *savedFramePtr;
+ CallFrame *savedFramePtr = NULL;
char *name;
/*
@@ -3476,66 +3476,57 @@ Tcl_GetCommandFromObj(
* 456668]
*/
- savedFramePtr = iPtr->varFramePtr;
name = Tcl_GetString(objPtr);
if ((*name++ == ':') && (*name == ':')) {
+ savedFramePtr = iPtr->varFramePtr;
iPtr->varFramePtr = iPtr->rootFramePtr;
}
/*
- * Get the internal representation, converting to a command type if
- * needed. The internal representation is a ResolvedCmdName that points to
- * the actual command.
- */
-
- if (objPtr->typePtr != &tclCmdNameType) {
- result = tclCmdNameType.setFromAnyProc(interp, objPtr);
- if (result != TCL_OK) {
- iPtr->varFramePtr = savedFramePtr;
- return (Tcl_Command) NULL;
- }
- }
- resPtr = (ResolvedCmdName *) objPtr->internalRep.twoPtrValue.ptr1;
-
- /*
* Get the current namespace.
*/
currNsPtr = iPtr->varFramePtr->nsPtr;
/*
+ * Get the internal representation, converting to a command type if
+ * needed. The internal representation is a ResolvedCmdName that points to
+ * the actual command.
+ *
* Check the context namespace and the namespace epoch of the resolved
- * symbol to make sure that it is fresh. If not, then force another
- * conversion to the command type, to discard the old rep and create a new
- * one. Note that we verify that the namespace id of the context namespace
- * is the same as the one we cached; this insures that the namespace
- * wasn't deleted and a new one created at the same address with the same
- * command epoch.
+ * symbol to make sure that it is fresh. Note that we verify that the
+ * namespace id of the context namespace is the same as the one we cached;
+ * this insures that the namespace wasn't deleted and a new one created at
+ * the same address with the same command epoch.
+ *
+ * Check also that the command's epoch is up to date, and that the command
+ * is not deleted.
+ *
+ * If any check fails, then force another conversion to the command type,
+ * to discard the old rep and create a new one.
*/
- cmdPtr = NULL;
- if ((resPtr != NULL)
- && (resPtr->refNsPtr == currNsPtr)
- && (resPtr->refNsId == currNsPtr->nsId)
- && (resPtr->refNsCmdEpoch == currNsPtr->cmdRefEpoch)) {
- cmdPtr = resPtr->cmdPtr;
- if ((cmdPtr->cmdEpoch != resPtr->cmdEpoch) || (cmdPtr->flags & CMD_IS_DELETED)) {
- cmdPtr = NULL;
- }
- }
+ resPtr = (ResolvedCmdName *) objPtr->internalRep.twoPtrValue.ptr1;
+ if ((objPtr->typePtr != &tclCmdNameType)
+ || (resPtr == NULL)
+ || (resPtr->refNsPtr != currNsPtr)
+ || (resPtr->refNsId != currNsPtr->nsId)
+ || (resPtr->refNsCmdEpoch != currNsPtr->cmdRefEpoch)
+ || (cmdPtr = resPtr->cmdPtr, cmdPtr->cmdEpoch != resPtr->cmdEpoch)
+ || (cmdPtr->flags & CMD_IS_DELETED)) {
- if (cmdPtr == NULL) {
result = tclCmdNameType.setFromAnyProc(interp, objPtr);
- if (result != TCL_OK) {
- iPtr->varFramePtr = savedFramePtr;
- return (Tcl_Command) NULL;
- }
resPtr = (ResolvedCmdName *) objPtr->internalRep.twoPtrValue.ptr1;
- if (resPtr != NULL) {
+ if ((result == TCL_OK) && resPtr) {
cmdPtr = resPtr->cmdPtr;
+ } else {
+ cmdPtr = NULL;
}
}
- iPtr->varFramePtr = savedFramePtr;
+
+ if (savedFramePtr) {
+ iPtr->varFramePtr = savedFramePtr;
+ }
return (Tcl_Command) cmdPtr;
}