summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2015-12-12 19:45:05 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2015-12-12 19:45:05 (GMT)
commit95c3cb75580432d8b130a8e5041402e3d9d31927 (patch)
treea8612344bc46371e92505a156b55def24e8354f9
parentd2307504cb8e9abfc1734f2311befbf85cbb5425 (diff)
downloadtcl-95c3cb75580432d8b130a8e5041402e3d9d31927.zip
tcl-95c3cb75580432d8b130a8e5041402e3d9d31927.tar.gz
tcl-95c3cb75580432d8b130a8e5041402e3d9d31927.tar.bz2
remove trampoline bounces: invoke commands directly from tebc
-rw-r--r--generic/tclBasic.c3
-rw-r--r--generic/tclCompile.h1
-rw-r--r--generic/tclExecute.c20
3 files changed, 22 insertions, 2 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 1575048..def25c4 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -128,7 +128,6 @@ static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
int actual, Tcl_Obj *const *objv);
static Tcl_NRPostProc NRCoroutineCallerCallback;
static Tcl_NRPostProc NRCoroutineExitCallback;
-static int NRCommand(ClientData data[], Tcl_Interp *interp, int result);
static int NRRoot(ClientData data[], Tcl_Interp *interp, int result);
#if !NRE_STACK_DEBUG
static Tcl_NRPostProc NRStackBottom;
@@ -4397,7 +4396,7 @@ NRRoot(
return result;
}
-static int
+int
NRCommand(
ClientData data[],
Tcl_Interp *interp,
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
index eba506a..d8eec12 100644
--- a/generic/tclCompile.h
+++ b/generic/tclCompile.h
@@ -1086,6 +1086,7 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
register Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[], int isLambda);
+MODULE_SCOPE int NRCommand(ClientData data[], Tcl_Interp *interp, int result);
/*
*----------------------------------------------------------------
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 0b8f71e..f141c49 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -3009,6 +3009,26 @@ TEBCresume(
pc += pcAdjustment;
TEBC_YIELD();
+
+ iPtr->numLevels++;
+ if (TCL_OK == TclInterpReady(interp)) {
+ /*
+ * If everything is OK, avoid going to TclNREvalObjv and do the
+ * job directly here.
+ */
+
+ Command *cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[0]);
+ if (cmdPtr && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES) && !iPtr->tracePtr ) {
+ iPtr->ensembleRewrite.sourceObjs = NULL;
+ TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL);
+ if (cmdPtr->nreProc) {
+ return cmdPtr->nreProc(cmdPtr->objClientData, interp, objc, objv);
+ } else {
+ return cmdPtr->objProc(cmdPtr->objClientData, interp, objc, objv);
+ }
+ }
+ }
+ iPtr->numLevels--;
return TclNREvalObjv(interp, objc, objv,
TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME, NULL);