summaryrefslogtreecommitdiffstats
path: root/generic/tclCompile.h
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclCompile.h')
-rw-r--r--generic/tclCompile.h74
1 files changed, 73 insertions, 1 deletions
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
index 15b5477..ebd57f1 100644
--- a/generic/tclCompile.h
+++ b/generic/tclCompile.h
@@ -779,8 +779,10 @@ typedef struct ByteCode {
#define INST_EXPAND_DROP 165
+#define INST_VERIFY 166
+
/* The last opcode */
-#define LAST_INST_OPCODE 165
+#define LAST_INST_OPCODE 166
/*
* Table describing the Tcl bytecode instructions: their name (for displaying
@@ -1147,6 +1149,27 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
* void TclAdjustStackDepth(int delta, CompileEnv *envPtr);
*/
+#if defined(TCL_COMPILE_DEBUG)
+#define VerifyStackDepth(envPtr) \
+ do { \
+ int i = (envPtr)->currStackDepth; \
+ if (((envPtr)->codeNext + 5) > (envPtr)->codeEnd) { \
+ TclExpandCodeArray(envPtr); \
+ } \
+ *(envPtr)->codeNext++ = (unsigned char) INST_VERIFY; \
+ *(envPtr)->codeNext++ = \
+ (unsigned char) ((unsigned int) (i) >> 24); \
+ *(envPtr)->codeNext++ = \
+ (unsigned char) ((unsigned int) (i) >> 16); \
+ *(envPtr)->codeNext++ = \
+ (unsigned char) ((unsigned int) (i) >> 8); \
+ *(envPtr)->codeNext++ = \
+ (unsigned char) ((unsigned int) (i) ); \
+ } while (0)
+#else
+#define VerifyStackDepth(envPtr)
+#endif
+
#define TclAdjustStackDepth(delta, envPtr) \
do { \
if ((delta) < 0) { \
@@ -1155,6 +1178,7 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
} \
} \
(envPtr)->currStackDepth += (delta); \
+ VerifyStackDepth(envPtr); \
} while (0)
/*
@@ -1215,14 +1239,61 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
* void TclEmitInt4(int i, CompileEnv *envPtr);
*/
+
+#if defined(TCL_COMPILE_DEBUG)
#define TclEmitInt1(i, envPtr) \
do { \
if ((envPtr)->codeNext == (envPtr)->codeEnd) { \
TclExpandCodeArray(envPtr); \
} \
+ if ((envPtr)->codeNext[-5] == INST_VERIFY) { \
+ memmove((envPtr)->codeNext-4, (envPtr)->codeNext-5, 5); \
+ (envPtr)->codeNext[-5] = \
+ (unsigned char) ((unsigned int) (i)); \
+ (envPtr)->codeNext++; \
+ break; \
+ } \
*(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i)); \
} while (0)
+#else
+#define TclEmitInt1(i, envPtr) \
+ do { \
+ if ((envPtr)->codeNext == (envPtr)->codeEnd) { \
+ TclExpandCodeArray(envPtr); \
+ } \
+ *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i)); \
+ } while (0)
+#endif
+#if defined(TCL_COMPILE_DEBUG)
+#define TclEmitInt4(i, envPtr) \
+ do { \
+ if (((envPtr)->codeNext + 4) > (envPtr)->codeEnd) { \
+ TclExpandCodeArray(envPtr); \
+ } \
+ if ((envPtr)->codeNext[-5] == INST_VERIFY) { \
+ memmove((envPtr)->codeNext-1, (envPtr)->codeNext-5, 5); \
+ (envPtr)->codeNext[-5] = \
+ (unsigned char) ((unsigned int) (i) >> 24); \
+ (envPtr)->codeNext[-4] = \
+ (unsigned char) ((unsigned int) (i) >> 16); \
+ (envPtr)->codeNext[-3] = \
+ (unsigned char) ((unsigned int) (i) >> 8); \
+ (envPtr)->codeNext[-2] = \
+ (unsigned char) ((unsigned int) (i) ); \
+ (envPtr)->codeNext += 4; \
+ break; \
+ } \
+ *(envPtr)->codeNext++ = \
+ (unsigned char) ((unsigned int) (i) >> 24); \
+ *(envPtr)->codeNext++ = \
+ (unsigned char) ((unsigned int) (i) >> 16); \
+ *(envPtr)->codeNext++ = \
+ (unsigned char) ((unsigned int) (i) >> 8); \
+ *(envPtr)->codeNext++ = \
+ (unsigned char) ((unsigned int) (i) ); \
+ } while (0)
+#else
#define TclEmitInt4(i, envPtr) \
do { \
if (((envPtr)->codeNext + 4) > (envPtr)->codeEnd) { \
@@ -1237,6 +1308,7 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
*(envPtr)->codeNext++ = \
(unsigned char) ((unsigned int) (i) ); \
} while (0)
+#endif
/*
* Macros to emit an instruction with signed or unsigned integer operands.