summaryrefslogtreecommitdiffstats
path: root/generic/tclAssembly.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2013-10-20 18:15:08 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2013-10-20 18:15:08 (GMT)
commitff83c9993b14e1a40c0003bbda71dbbf2fe79a98 (patch)
tree0733388d31d6723b8dbe3d4f2976ef2178516cae /generic/tclAssembly.c
parent6df7d9226ad0c3c3721e54bcb2d7a4b9fe914b93 (diff)
parent39e314ad912cdbd29ba3e01673b1097b40118f8b (diff)
downloadtcl-ff83c9993b14e1a40c0003bbda71dbbf2fe79a98.zip
tcl-ff83c9993b14e1a40c0003bbda71dbbf2fe79a98.tar.gz
tcl-ff83c9993b14e1a40c0003bbda71dbbf2fe79a98.tar.bz2
[2835313] Ensure correct stack balance when break and continue exceptions are about: the hard cases with potential concealed exception generation.
Diffstat (limited to 'generic/tclAssembly.c')
-rw-r--r--generic/tclAssembly.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c
index 946c729..fc51457 100644
--- a/generic/tclAssembly.c
+++ b/generic/tclAssembly.c
@@ -246,6 +246,8 @@ static void BBEmitInstInt4(AssemblyEnv* assemEnvPtr, int tblIdx,
int opnd, int count);
static void BBEmitInst1or4(AssemblyEnv* assemEnvPtr, int tblIdx,
int param, int count);
+static void BBEmitInvoke1or4(AssemblyEnv* assemEnvPtr, int tblIdx,
+ int param, int count);
static void BBEmitOpcode(AssemblyEnv* assemEnvPtr, int tblIdx,
int count);
static int BuildExceptionRanges(AssemblyEnv* assemEnvPtr);
@@ -679,10 +681,13 @@ BBEmitInstInt4(
/*
*-----------------------------------------------------------------------------
*
- * BBEmitInst1or4 --
+ * BBEmitInst1or4, BBEmitInvoke1or4 --
*
* Emits a 1- or 4-byte operation according to the magnitude of the
- * operand
+ * operand. The Invoke variant generates wrapping stack-balance
+ * management if necessary (which is not normally required in assembled
+ * code, as loop exception ranges, expansions, breaks and continues can't
+ * be issued currently).
*
*-----------------------------------------------------------------------------
*/
@@ -714,6 +719,29 @@ BBEmitInst1or4(
TclUpdateAtCmdStart(op, envPtr);
BBUpdateStackReqs(bbPtr, tblIdx, count);
}
+
+static void
+BBEmitInvoke1or4(
+ AssemblyEnv* assemEnvPtr, /* Assembly environment */
+ int tblIdx, /* Index in TalInstructionTable of op */
+ int param, /* Variable-length parameter */
+ int count) /* Arity if variadic */
+{
+ CompileEnv* envPtr = assemEnvPtr->envPtr;
+ /* Compilation environment */
+ BasicBlock* bbPtr = assemEnvPtr->curr_bb;
+ /* Current basic block */
+ int op = TalInstructionTable[tblIdx].tclInstCode;
+
+ if (param <= 0xff) {
+ op >>= 8;
+ } else {
+ op &= 0xff;
+ }
+ TclEmitInvoke(envPtr, op, param);
+ TclUpdateAtCmdStart(op, envPtr);
+ BBUpdateStackReqs(bbPtr, tblIdx, count);
+}
/*
*-----------------------------------------------------------------------------
@@ -1450,7 +1478,7 @@ AssembleOneLine(
goto cleanup;
}
- BBEmitInst1or4(assemEnvPtr, tblIdx, opnd, opnd);
+ BBEmitInvoke1or4(assemEnvPtr, tblIdx, opnd, opnd);
break;
case ASSEM_JUMP: