summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclBasic.c16
-rw-r--r--generic/tclExecute.c17
-rw-r--r--generic/tclNRE.h17
-rw-r--r--generic/tclTest.c22
-rw-r--r--unix/Makefile.in2
5 files changed, 40 insertions, 34 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index cb14afd..dfd27d2 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -4285,17 +4285,19 @@ EvalObjvCore(
int
TclNRRunCallbacks(
Tcl_Interp *interp,
- int result) /* Callbacks are run until the first NRRoot.*/
+ int result)
{
NRE_callback *cbPtr;
- Tcl_NRPostProc *procPtr;
- while (TOP_CB(interp) && (TOP_CB(interp)->procPtr != NRRoot)) {
- POP_CB(interp, cbPtr);
- procPtr = cbPtr->procPtr;
- result = procPtr(cbPtr->data, interp, result);
- }
+ /* Callbacks are run until the first NRRoot.*/
+
+ do {
+ POP_CB(interp, cbPtr);
+ result = (cbPtr->procPtr)(cbPtr->data, interp, result);
+ } while (TOP_CB(interp) && (TOP_CB(interp)->procPtr != NRRoot));
+
if (TOP_CB(interp)) {
+ /* pop the remaining NRRoot */
POP_CB(interp, cbPtr);
}
return result;
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index cbeaba3..05896f1 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -2817,23 +2817,6 @@ TEBCresume(
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);
diff --git a/generic/tclNRE.h b/generic/tclNRE.h
index ca8dd7f..c1df6d2 100644
--- a/generic/tclNRE.h
+++ b/generic/tclNRE.h
@@ -63,12 +63,25 @@ typedef struct NRE_stack {
#define NEXT_CB(ptr) TclNextCallback(ptr)
+#define NRE_TRAMPOLINE 0
+#if NRE_TRAMPOLINE
+#define NRE_JUMP(interp,postProcPtr,data0,data1,data2,data3) \
+ TclNRAddCallback((interp),(postProcPtr),(data0),(data1),(data2),(data3)); \
+ NRE_NEXT(TCL_OK)
#define NRE_NEXT(result) \
return (result)
-
+#else
+/* no trampoline, optimized sibcalls */
#define NRE_JUMP(interp,postProcPtr,data0,data1,data2,data3) \
TclNRAddCallback((interp),(postProcPtr),(data0),(data1),(data2),(data3)); \
- NRE_NEXT(TCL_OK)
+ return TCL_OK
+#define NRE_NEXT(result) \
+ do { /* optimized indirect sibling calls?! */ \
+ NRE_callback *cbPtr; \
+ POP_CB(interp, cbPtr); \
+ return (cbPtr->procPtr)(cbPtr->data, interp, result); \
+ } while (0)
+#endif
MODULE_SCOPE TCL_NOINLINE NRE_callback *TclNewCallback(Tcl_Interp *interp);
MODULE_SCOPE TCL_NOINLINE NRE_callback *TclPopCallback(Tcl_Interp *interp);
diff --git a/generic/tclTest.c b/generic/tclTest.c
index aa75738..baf54ec 100644
--- a/generic/tclTest.c
+++ b/generic/tclTest.c
@@ -394,6 +394,7 @@ static int TestHashSystemHashCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+static TCL_NOINLINE void *NRE_depth(void);
static int NREUnwind_callback(ClientData data[], Tcl_Interp *interp,
int result);
static int TestNREUnwind(ClientData clientData,
@@ -6557,31 +6558,38 @@ TestgetintCmd(
}
}
+
+static TCL_NOINLINE void *
+NRE_depth(
+ void)
+{
+ int none;
+ return &none;
+}
+
static int
NREUnwind_callback(
ClientData data[],
Tcl_Interp *interp,
int result)
{
- int none;
-
if (data[0] == INT2PTR(-1)) {
- TclNRAddCallback(interp, NREUnwind_callback, &none, INT2PTR(-1),
+ TclNRAddCallback(interp, NREUnwind_callback, NRE_depth(), INT2PTR(-1),
INT2PTR(-1), NULL);
} else if (data[1] == INT2PTR(-1)) {
- TclNRAddCallback(interp, NREUnwind_callback, data[0], &none,
+ TclNRAddCallback(interp, NREUnwind_callback, data[0], NRE_depth(),
INT2PTR(-1), NULL);
} else if (data[2] == INT2PTR(-1)) {
TclNRAddCallback(interp, NREUnwind_callback, data[0], data[1],
- &none, NULL);
+ NRE_depth(), NULL);
} else {
Tcl_Obj *idata[3];
idata[0] = Tcl_NewIntObj((int) (data[1] - data[0]));
idata[1] = Tcl_NewIntObj((int) (data[2] - data[0]));
- idata[2] = Tcl_NewIntObj((int) ((void *) &none - data[0]));
+ idata[2] = Tcl_NewIntObj((int) ((void *) NRE_depth() - data[0]));
Tcl_SetObjResult(interp, Tcl_NewListObj(3, idata));
}
- return TCL_OK;
+ NRE_NEXT(TCL_OK);
}
static int
diff --git a/unix/Makefile.in b/unix/Makefile.in
index ed9d9fb..de21f47 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -95,7 +95,7 @@ TCL_MODULE_PATH = @TCL_MODULE_PATH@
CFLAGS_WARNING = @CFLAGS_WARNING@
# The default switches for optimization or debugging
-CFLAGS_DEBUG = @CFLAGS_DEBUG@
+CFLAGS_DEBUG = @CFLAGS_DEBUG@ @CFLAGS_OPTIMIZE@
CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@
# To change the compiler switches, for example to change from optimization to