summaryrefslogtreecommitdiffstats
path: root/generic/tclNRE.h
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2016-01-26 16:59:29 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2016-01-26 16:59:29 (GMT)
commit9a6a7e39980e6125f37e6d87520ebf213ad83a4b (patch)
tree2c115d40d7c8f932a9746448ac12354bde42e89b /generic/tclNRE.h
parent1acb0742e2003b2986c75a8f0967b7a7fdd5d661 (diff)
downloadtcl-9a6a7e39980e6125f37e6d87520ebf213ad83a4b.zip
tcl-9a6a7e39980e6125f37e6d87520ebf213ad83a4b.tar.gz
tcl-9a6a7e39980e6125f37e6d87520ebf213ad83a4b.tar.bz2
using gcc's sibling call optimisation: calls between NRE_callbacks are optimised to tailcalls, also indirect calls
Diffstat (limited to 'generic/tclNRE.h')
-rw-r--r--generic/tclNRE.h17
1 files changed, 15 insertions, 2 deletions
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);