summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c98
1 files changed, 61 insertions, 37 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 554e5d2..7b08f66 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -16,7 +16,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.318 2008/07/21 03:49:52 msofer Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.319 2008/07/21 16:26:01 msofer Exp $
*/
#include "tclInt.h"
@@ -3918,10 +3918,27 @@ Tcl_EvalObjv(
* TCL_EVAL_GLOBAL, TCL_EVAL_INVOKE and
* TCL_EVAL_NOERR are currently supported. */
{
- Command *cmdPtr;
+ return TclEvalObjv(interp, objc, objv, flags, NULL);
+}
+
+int
+TclEvalObjv(
+ Tcl_Interp *interp, /* Interpreter in which to evaluate the
+ * command. Also used for error reporting. */
+ int objc, /* Number of words in command. */
+ Tcl_Obj *const objv[], /* An array of pointers to objects that are
+ * the words that make up the command. */
+ int flags, /* Collection of OR-ed bits that control the
+ * evaluation of the script. Only
+ * TCL_EVAL_GLOBAL, TCL_EVAL_INVOKE and
+ * TCL_EVAL_NOERR are currently supported. */
+ Command *cmdPtr) /* NULL if the Command is to be looked up
+ * here, otherwise the pointer to the
+ * requested Command struct to be invoked. */
+{
Interp *iPtr = (Interp *) interp;
int result;
- Namespace *lookupNsPtr;
+ Namespace *lookupNsPtr = NULL;
TEOV_record *rootPtr = TOP_RECORD(iPtr);
TEOV_record *recordPtr;
Tcl_ObjCmdProc *objProc;
@@ -3930,6 +3947,14 @@ Tcl_EvalObjv(
TEBC_CALL(iPtr) = 0;
+ if (cmdPtr) {
+ if (iPtr->lookupNsPtr) {
+ iPtr->lookupNsPtr = NULL;
+ }
+ PUSH_RECORD(interp, recordPtr);
+ goto commandFound;
+ }
+
restartAtTop:
TclResetCancellation(interp, 0);
iPtr->numLevels++;
@@ -3993,6 +4018,18 @@ Tcl_EvalObjv(
goto done;
}
+ iPtr->cmdCount++;
+ if (TclLimitExceeded(iPtr->limit)) {
+ result = TCL_ERROR;
+ iPtr->numLevels--;
+ goto done;
+ }
+
+ /*
+ * Found a command! The real work begins now ...
+ */
+
+ commandFound:
if (iPtr->tracePtr || (cmdPtr->flags & CMD_HAS_EXEC_TRACES)) {
/*
* Call enter traces. They will schedule a call to the leave traces if
@@ -4009,10 +4046,6 @@ Tcl_EvalObjv(
}
}
- /*
- * Found a command! The real work begins now ...
- */
-
if (TCL_DTRACE_CMD_ARGS_ENABLED()) {
char *a[10];
int i = 0;
@@ -4050,13 +4083,6 @@ Tcl_EvalObjv(
* where it really belongs, and do not really know what it does either.
*/
- iPtr->cmdCount++;
- if (TclLimitExceeded(iPtr->limit)) {
- result = TCL_ERROR;
- iPtr->numLevels--;
- goto done;
- }
-
objProc = cmdPtr->nreProc;
if (!objProc) {
objProc = cmdPtr->objProc;
@@ -4066,13 +4092,12 @@ Tcl_EvalObjv(
COMPLETE_RECORD(recordPtr);
cmdPtr->refCount++;
- objProcReentryPoint:
/*
* If this is an NR-enabled command, find the real objProc.
*/
result = (*objProc)(objClientData, interp, objc, objv);
- if ((result != TCL_OK) || !VALID_NEW_REQUEST(recordPtr)) {
+ if (result != TCL_OK) {
#if 0
TclStackPurge(interp, recordPtr->tosPtr);
#endif
@@ -4150,16 +4175,16 @@ Tcl_EvalObjv(
}
goto done;
}
- case TCL_NR_OBJPROC_TYPE:
+ case TCL_NR_CMDSWAP_TYPE:
/*
- * This is a rewrite like ns-import does, without a new cmdPtr or new
- * reentrant call. FIXME NRE: add edition of objc/objv?
+ * This is a cmdPtr swap like ns-import does.
*/
- objProc = recordPtr->data.objProc.objProc;
- objClientData = recordPtr->data.objProc.clientData;
+ cmdPtr = recordPtr->cmdPtr;
+ objc = recordPtr->data.objcv.objc;
+ objv = recordPtr->data.objcv.objv;
recordPtr->type = TCL_NR_NO_TYPE;
- goto objProcReentryPoint;
+ goto commandFound;
default:
Tcl_Panic("TEOV: unknown NR-request type %i!", recordPtr->type);
}
@@ -4229,6 +4254,7 @@ TclEvalObjv_NR2(
case TCL_NR_BC_TYPE:
case TCL_NR_CMD_TYPE:
case TCL_NR_SCRIPT_TYPE:
+ case TCL_NR_CMDSWAP_TYPE:
goto done;
case TCL_NR_TAILCALL_TYPE:
Tcl_Panic("Tailcall called from a callback!");
@@ -7419,7 +7445,7 @@ NRPostProcess(
"impossible to tailcall from a non-NRE enabled command",
TCL_STATIC);
result = TCL_ERROR;
- break;
+ break;
case TCL_NR_CMD_TYPE: {
Tcl_Obj *objPtr = recordPtr->data.obj.objPtr;
int flags = recordPtr->data.obj.flags;
@@ -7437,14 +7463,9 @@ NRPostProcess(
result = TclNREvalObjEx(interp, objPtr, flags, NULL, 0);
break;
}
- case TCL_NR_OBJPROC_TYPE: {
- Tcl_ObjCmdProc *objProc = recordPtr->data.objProc.objProc;
- ClientData clientData = recordPtr->data.objProc.clientData;
-
- if (!objc) {
- Tcl_Panic("NRPostProcess: something is very wrong!");
- }
- result = (*objProc)(clientData, interp, objc, objv);
+ case TCL_NR_CMDSWAP_TYPE: {
+ result = TclEvalObjv(interp, recordPtr->data.objcv.objc,
+ recordPtr->data.objcv.objv, 0, recordPtr->cmdPtr);
break;
}
default:
@@ -7593,16 +7614,19 @@ Tcl_NREvalObj(
}
int
-Tcl_NRObjProc(
+Tcl_NRCmdSwap(
Tcl_Interp *interp,
- Tcl_ObjCmdProc *objProc,
- ClientData clientData)
+ Tcl_Command cmd,
+ int objc,
+ Tcl_Obj *const objv[])
{
TEOV_record *recordPtr = TOP_RECORD(interp);
- recordPtr->type = TCL_NR_OBJPROC_TYPE;
- recordPtr->data.objProc.objProc = objProc;
- recordPtr->data.objProc.clientData = clientData;
+ recordPtr->type = TCL_NR_CMDSWAP_TYPE;
+ recordPtr->cmdPtr = (Command *) cmd;
+ recordPtr->data.objcv.objc = objc;
+ recordPtr->data.objcv.objv = (Tcl_Obj **) objv;
+
return TCL_OK;
}