Compare commits
66
Commits
http3
...
mig-optimize
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
493708345c | ||
|
|
cc25eb0ef8 | ||
|
|
bf50d3f180 | ||
|
|
6b42e94b12 | ||
|
|
f47b7cf634 | ||
|
|
ac159b6f8f | ||
|
|
332270bb3d | ||
|
|
539e23813f | ||
|
|
3e4e5a925c | ||
|
|
565480a20e | ||
|
|
f6132adb44 | ||
|
|
db9b67529e | ||
|
|
9229e40b33 | ||
|
|
27d74901b1 | ||
|
|
1095c2f3a6 | ||
|
|
0ffa0f502b | ||
|
|
64466a8da1 | ||
|
|
2ec3ddbdc1 | ||
|
|
f2092d8451 | ||
|
|
44ced2e326 | ||
|
|
bf2bd69b16 | ||
|
|
4ebd2624b7 | ||
|
|
c81eb8b1a3 | ||
|
|
8c2626f85d | ||
|
|
447bb823fa | ||
|
|
b089f1b4fa | ||
|
|
44199cbff3 | ||
|
|
53e3336549 | ||
|
|
6317b5fd69 | ||
|
|
90ef9d7f8e | ||
|
|
ad3ce931d4 | ||
|
|
dd0af72708 | ||
|
|
4f775ee25f | ||
|
|
b075d3c4eb | ||
|
|
8fbcfb3377 | ||
|
|
7557b763d7 | ||
|
|
d8152de14e | ||
|
|
75cdfb0d22 | ||
|
|
ff95a82499 | ||
|
|
bf6bfb1c3d | ||
|
|
c79209cc3b | ||
|
|
ec66433113 | ||
|
|
398b2996aa | ||
|
|
1a1816ad5a | ||
|
|
0d105ffe65 | ||
|
|
347dbf12a8 | ||
|
|
14405a384a | ||
|
|
be3d8d6a8c | ||
|
|
594e8f05e6 | ||
|
|
ac45b197f9 | ||
|
|
d331f7d46f | ||
|
|
86967f2e5f | ||
|
|
3e4a52652c | ||
|
|
3f1f410536 | ||
|
|
a611377458 | ||
|
|
e787f85ab3 | ||
|
|
76230e8486 | ||
|
|
d41185c001 | ||
|
|
7e05eabf85 | ||
|
|
673818c80c | ||
|
|
509ce7a5b4 | ||
|
|
4a163f0632 | ||
|
|
87d1ff783c | ||
|
|
cff8cdded6 | ||
|
|
3b9f237d69 | ||
|
|
dd7738413b |
+73
-87
@@ -268,7 +268,7 @@ TclCompileArraySetCmd(
|
||||
int isScalar, localIndex, code = TCL_OK;
|
||||
int isDataLiteral, isDataValid, isDataEven, len;
|
||||
int keyVar, valVar, infoIndex;
|
||||
int fwd, offsetBack, offsetFwd;
|
||||
int offsetBack, offsetFwd;
|
||||
Tcl_Obj *literalObj;
|
||||
ForeachInfo *infoPtr;
|
||||
|
||||
@@ -320,20 +320,23 @@ TclCompileArraySetCmd(
|
||||
*/
|
||||
|
||||
if (isDataEven && len == 0) {
|
||||
int jumpEnd, jumpPop;
|
||||
if (localIndex >= 0) {
|
||||
TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
|
||||
TclEmitInstInt1(INST_JUMP_TRUE1, 7, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP_TRUE, &jumpEnd);
|
||||
TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex, envPtr);
|
||||
} else {
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_ARRAY_EXISTS_STK, envPtr);
|
||||
TclEmitInstInt1(INST_JUMP_TRUE1, 5, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP_TRUE, &jumpPop);
|
||||
TclEmitOpcode( INST_ARRAY_MAKE_STK, envPtr);
|
||||
TclEmitInstInt1(INST_JUMP1, 3, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP, &jumpEnd);
|
||||
/* Each branch decrements stack depth, but we only take one. */
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
TclFixupForwardJumpToHere(envPtr, jumpPop);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, jumpEnd);
|
||||
PushStringLiteral(envPtr, "");
|
||||
goto done;
|
||||
}
|
||||
@@ -384,19 +387,17 @@ TclCompileArraySetCmd(
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
PushStringLiteral(envPtr, "1");
|
||||
TclEmitOpcode( INST_BITAND, envPtr);
|
||||
offsetFwd = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1(INST_JUMP_FALSE1, 0, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP_FALSE, &offsetFwd);
|
||||
PushStringLiteral(envPtr, "list must have an even number of elements");
|
||||
PushStringLiteral(envPtr, "-errorcode {TCL ARGUMENT FORMAT}");
|
||||
TclEmitInstInt4(INST_RETURN_IMM, TCL_ERROR, envPtr);
|
||||
TclEmitInt4( 0, envPtr);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
fwd = CurrentOffset(envPtr) - offsetFwd;
|
||||
TclStoreInt1AtPtr(fwd, envPtr->codeStart+offsetFwd+1);
|
||||
TclFixupForwardJumpToHere(envPtr, offsetFwd);
|
||||
}
|
||||
|
||||
TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
|
||||
TclEmitInstInt1(INST_JUMP_TRUE1, 7, envPtr);
|
||||
TclEmitInstInt4(INST_JUMP_TRUE4, 10, envPtr);
|
||||
TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex, envPtr);
|
||||
TclEmitInstInt4(INST_FOREACH_START, infoIndex, envPtr);
|
||||
offsetBack = CurrentOffset(envPtr);
|
||||
@@ -427,6 +428,7 @@ TclCompileArrayUnsetCmd(
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
int isScalar, localIndex;
|
||||
int jumpEnd, jumpPop;
|
||||
|
||||
if (parsePtr->numWords != 2) {
|
||||
return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
|
||||
@@ -440,19 +442,21 @@ TclCompileArrayUnsetCmd(
|
||||
|
||||
if (localIndex >= 0) {
|
||||
TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
|
||||
TclEmitInstInt1(INST_JUMP_FALSE1, 8, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP_FALSE, &jumpEnd);
|
||||
TclEmitInstInt1(INST_UNSET_SCALAR, 1, envPtr);
|
||||
TclEmitInt4( localIndex, envPtr);
|
||||
} else {
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_ARRAY_EXISTS_STK, envPtr);
|
||||
TclEmitInstInt1(INST_JUMP_FALSE1, 6, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP_FALSE, &jumpPop);
|
||||
TclEmitInstInt1(INST_UNSET_STK, 1, envPtr);
|
||||
TclEmitInstInt1(INST_JUMP1, 3, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP, &jumpEnd);
|
||||
/* Each branch decrements stack depth, but we only take one. */
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
TclFixupForwardJumpToHere(envPtr, jumpPop);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, jumpEnd);
|
||||
PushStringLiteral(envPtr, "");
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -542,7 +546,7 @@ TclCompileCatchCmd(
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
JumpFixup jumpFixup;
|
||||
int jumpFixup;
|
||||
Tcl_Token *cmdTokenPtr, *resultNameTokenPtr, *optsNameTokenPtr;
|
||||
int resultIndex, optsIndex, range, dropScript = 0;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
@@ -625,16 +629,32 @@ TclCompileCatchCmd(
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
|
||||
TclCheckStackDepth(depth+1, envPtr);
|
||||
|
||||
/*
|
||||
* Emit the "no errors" epilogue: push "0" (TCL_OK) as the catch result,
|
||||
* and jump around the "error case" code.
|
||||
* Emit the "no errors" epilogue: last instruction is push "0" (TCL_OK)
|
||||
* as the catch result, and jump to the end. There is some code
|
||||
* duplication in order to allow the optimization of the OK case.
|
||||
*
|
||||
* NOTE: see comments on instruction ordering below!
|
||||
*/
|
||||
|
||||
TclCheckStackDepth(depth+1, envPtr);
|
||||
if (optsIndex != -1) {
|
||||
TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
|
||||
}
|
||||
TclEmitOpcode( INST_END_CATCH, envPtr);
|
||||
if (optsIndex != -1) {
|
||||
Emit14Inst( INST_STORE_SCALAR, optsIndex, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
if (resultIndex != -1) {
|
||||
Emit14Inst( INST_STORE_SCALAR, resultIndex, envPtr);
|
||||
}
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
TclCheckStackDepth(depth, envPtr);
|
||||
|
||||
PushStringLiteral(envPtr, "0");
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP, &jumpFixup);
|
||||
|
||||
/*
|
||||
* Emit the "error case" epilogue. Push the interpreter result and the
|
||||
@@ -642,37 +662,25 @@ TclCompileCatchCmd(
|
||||
*/
|
||||
|
||||
ExceptionRangeTarget(envPtr, range, catchOffset);
|
||||
|
||||
/* Stack at this point is empty. Push the return code, then push the
|
||||
* result and return options if the caller wants them. This needs to
|
||||
* happen before INST_END_CATCH.
|
||||
*/
|
||||
|
||||
TclSetStackDepth(depth + dropScript, envPtr);
|
||||
|
||||
if (dropScript) {
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
|
||||
|
||||
/* Stack at this point is empty */
|
||||
TclEmitOpcode( INST_PUSH_RESULT, envPtr);
|
||||
TclEmitOpcode( INST_PUSH_RETURN_CODE, envPtr);
|
||||
|
||||
/* Stack at this point on both branches: result returnCode */
|
||||
|
||||
if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
|
||||
Tcl_Panic("TclCompileCatchCmd: bad jump distance %d",
|
||||
(int)(CurrentOffset(envPtr) - jumpFixup.codeOffset));
|
||||
if (resultIndex != -1) {
|
||||
TclEmitOpcode( INST_PUSH_RESULT, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Push the return options if the caller wants them. This needs to happen
|
||||
* before INST_END_CATCH
|
||||
*/
|
||||
|
||||
if (optsIndex != -1) {
|
||||
TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* End the catch
|
||||
*/
|
||||
|
||||
TclEmitOpcode( INST_END_CATCH, envPtr);
|
||||
|
||||
/*
|
||||
@@ -684,19 +692,12 @@ TclCompileCatchCmd(
|
||||
Emit14Inst( INST_STORE_SCALAR, optsIndex, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, the top of the stack is inconveniently ordered:
|
||||
* result returnCode
|
||||
* Reverse the stack to store the result.
|
||||
*/
|
||||
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
if (resultIndex != -1) {
|
||||
Emit14Inst( INST_STORE_SCALAR, resultIndex, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
|
||||
TclFixupForwardJumpToHere(envPtr, jumpFixup);
|
||||
TclCheckStackDepth(depth+1, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1226,7 +1227,7 @@ TclCompileDictMergeCmd(
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *tokenPtr;
|
||||
int i, workerIndex, infoIndex, outLoop;
|
||||
int i, workerIndex, infoIndex, outLoop, jumpTarget;
|
||||
|
||||
/*
|
||||
* Deal with some special edge cases. Note that in the case with one
|
||||
@@ -1277,6 +1278,7 @@ TclCompileDictMergeCmd(
|
||||
TclEmitInstInt4( INST_BEGIN_CATCH4, outLoop, envPtr);
|
||||
ExceptionRangeStarts(envPtr, outLoop);
|
||||
for (i=2 ; i<parsePtr->numWords ; i++) {
|
||||
int jumpPop;
|
||||
/*
|
||||
* Get the dictionary, and merge its pairs into the first dict (using
|
||||
* a small loop).
|
||||
@@ -1285,14 +1287,17 @@ TclCompileDictMergeCmd(
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
TclEmitInstInt4( INST_DICT_FIRST, infoIndex, envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_TRUE1, 24, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP_TRUE, &jumpPop);
|
||||
jumpTarget = CurrentOffset(envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitInstInt4( INST_DICT_SET, 1, envPtr);
|
||||
TclEmitInt4( workerIndex, envPtr);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
TclEmitInstInt4( INST_DICT_NEXT, infoIndex, envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_FALSE1, -20, envPtr);
|
||||
jumpTarget -= CurrentOffset(envPtr);
|
||||
TclEmitInstInt4( INST_JUMP_FALSE4, jumpTarget, envPtr);
|
||||
TclFixupForwardJumpToHere(envPtr, jumpPop);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
|
||||
@@ -1308,7 +1313,7 @@ TclCompileDictMergeCmd(
|
||||
Emit14Inst( INST_LOAD_SCALAR, workerIndex, envPtr);
|
||||
TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
|
||||
TclEmitInt4( workerIndex, envPtr);
|
||||
TclEmitInstInt1( INST_JUMP1, 18, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP, &jumpTarget);
|
||||
|
||||
/*
|
||||
* If an exception happens when starting to iterate over the second (and
|
||||
@@ -1325,6 +1330,7 @@ TclCompileDictMergeCmd(
|
||||
TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
|
||||
TclEmitInt4( infoIndex, envPtr);
|
||||
TclEmitOpcode( INST_RETURN_STK, envPtr);
|
||||
TclFixupForwardJumpToHere(envPtr, jumpTarget);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1475,8 +1481,7 @@ CompileDictEachCmd(
|
||||
ExceptionRangeStarts(envPtr, catchRange);
|
||||
|
||||
TclEmitInstInt4( INST_DICT_FIRST, infoIndex, envPtr);
|
||||
emptyTargetOffset = CurrentOffset(envPtr);
|
||||
TclEmitInstInt4( INST_JUMP_TRUE4, 0, envPtr);
|
||||
TclEmitForwardJump(envPtr, JUMP_TRUE, &emptyTargetOffset);
|
||||
|
||||
/*
|
||||
* Inside the iteration, write the loop variables.
|
||||
@@ -1525,10 +1530,11 @@ CompileDictEachCmd(
|
||||
|
||||
ExceptionRangeTarget(envPtr, loopRange, continueOffset);
|
||||
TclEmitInstInt4( INST_DICT_NEXT, infoIndex, envPtr);
|
||||
|
||||
jumpDisplacement = bodyTargetOffset - CurrentOffset(envPtr);
|
||||
TclEmitInstInt4( INST_JUMP_FALSE4, jumpDisplacement, envPtr);
|
||||
endTargetOffset = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP1, 0, envPtr);
|
||||
|
||||
TclEmitForwardJump(envPtr, JUMP, &endTargetOffset);
|
||||
|
||||
/*
|
||||
* Error handler "finally" clause, which force-terminates the iteration
|
||||
@@ -1554,12 +1560,8 @@ CompileDictEachCmd(
|
||||
* easy!) Note that we skip the END_CATCH. [Bug 1382528]
|
||||
*/
|
||||
|
||||
jumpDisplacement = CurrentOffset(envPtr) - emptyTargetOffset;
|
||||
TclUpdateInstInt4AtPc(INST_JUMP_TRUE4, jumpDisplacement,
|
||||
envPtr->codeStart + emptyTargetOffset);
|
||||
jumpDisplacement = CurrentOffset(envPtr) - endTargetOffset;
|
||||
TclUpdateInstInt1AtPc(INST_JUMP1, jumpDisplacement,
|
||||
envPtr->codeStart + endTargetOffset);
|
||||
TclFixupForwardJumpToHere(envPtr, emptyTargetOffset);
|
||||
TclFixupForwardJumpToHere(envPtr, endTargetOffset);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
ExceptionRangeTarget(envPtr, loopRange, breakOffset);
|
||||
@@ -1597,7 +1599,7 @@ TclCompileDictUpdateCmd(
|
||||
int i, dictIndex, numVars, range, infoIndex;
|
||||
Tcl_Token **keyTokenPtrs, *dictVarTokenPtr, *bodyTokenPtr, *tokenPtr;
|
||||
DictUpdateInfo *duiPtr;
|
||||
JumpFixup jumpFixup;
|
||||
int jumpFixup;
|
||||
|
||||
/*
|
||||
* There must be at least one argument after the command.
|
||||
@@ -1699,7 +1701,7 @@ TclCompileDictUpdateCmd(
|
||||
* Jump around the exceptional termination code.
|
||||
*/
|
||||
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP, &jumpFixup);
|
||||
|
||||
/*
|
||||
* Termination code for non-ok returns: stash the result and return
|
||||
@@ -1717,10 +1719,7 @@ TclCompileDictUpdateCmd(
|
||||
TclEmitInt4( infoIndex, envPtr);
|
||||
TclEmitInvoke(envPtr,INST_RETURN_STK);
|
||||
|
||||
if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
|
||||
Tcl_Panic("TclCompileDictCmd(update): bad jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - jumpFixup.codeOffset));
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, jumpFixup);
|
||||
TclStackFree(interp, keyTokenPtrs);
|
||||
return TCL_OK;
|
||||
|
||||
@@ -1848,7 +1847,7 @@ TclCompileDictWithCmd(
|
||||
int i, range, varNameTmp = -1, pathTmp = -1, keysTmp, gotPath;
|
||||
int dictVar, bodyIsEmpty = 1;
|
||||
Tcl_Token *varTokenPtr, *tokenPtr;
|
||||
JumpFixup jumpFixup;
|
||||
int jumpFixup;
|
||||
const char *ptr, *end;
|
||||
|
||||
/*
|
||||
@@ -2048,7 +2047,7 @@ TclCompileDictWithCmd(
|
||||
} else {
|
||||
TclEmitInstInt4( INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
|
||||
}
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP, &jumpFixup);
|
||||
|
||||
/*
|
||||
* Now fold the results back into the dictionary in the exception case.
|
||||
@@ -2079,10 +2078,7 @@ TclCompileDictWithCmd(
|
||||
* Prepare for the start of the next command.
|
||||
*/
|
||||
|
||||
if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
|
||||
Tcl_Panic("TclCompileDictCmd(update): bad jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - jumpFixup.codeOffset));
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, jumpFixup);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2314,7 +2310,7 @@ TclCompileForCmd(
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
Tcl_Token *startTokenPtr, *testTokenPtr, *nextTokenPtr, *bodyTokenPtr;
|
||||
JumpFixup jumpEvalCondFixup;
|
||||
int jumpEvalCondFixup;
|
||||
int bodyCodeOffset, nextCodeOffset, jumpDist;
|
||||
int bodyRange, nextRange;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
@@ -2366,7 +2362,7 @@ TclCompileForCmd(
|
||||
* if (result) goto B
|
||||
*/
|
||||
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpEvalCondFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP, &jumpEvalCondFixup);
|
||||
|
||||
/*
|
||||
* Compile the loop body.
|
||||
@@ -2396,31 +2392,21 @@ TclCompileForCmd(
|
||||
* terminates the for.
|
||||
*/
|
||||
|
||||
if (TclFixupForwardJumpToHere(envPtr, &jumpEvalCondFixup, 127)) {
|
||||
bodyCodeOffset += 3;
|
||||
nextCodeOffset += 3;
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, jumpEvalCondFixup);
|
||||
|
||||
SetLineInformation(2);
|
||||
TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
|
||||
|
||||
jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
|
||||
if (jumpDist > 127) {
|
||||
TclEmitInstInt4(INST_JUMP_TRUE4, -jumpDist, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt1(INST_JUMP_TRUE1, -jumpDist, envPtr);
|
||||
}
|
||||
TclEmitInstInt4(INST_JUMP_TRUE4, -jumpDist, envPtr);
|
||||
|
||||
/*
|
||||
* Fix the starting points of the exception ranges (may have moved due to
|
||||
* jump type modification) and set where the exceptions target.
|
||||
*/
|
||||
|
||||
envPtr->exceptArrayPtr[bodyRange].codeOffset = bodyCodeOffset;
|
||||
envPtr->exceptArrayPtr[bodyRange].continueOffset = nextCodeOffset;
|
||||
|
||||
envPtr->exceptArrayPtr[nextRange].codeOffset = nextCodeOffset;
|
||||
|
||||
ExceptionRangeTarget(envPtr, bodyRange, breakOffset);
|
||||
ExceptionRangeTarget(envPtr, nextRange, breakOffset);
|
||||
TclFinalizeLoopExceptionRange(envPtr, bodyRange);
|
||||
|
||||
+10
-40
@@ -196,7 +196,7 @@ TclCompileIfCmd(
|
||||
* determined. */
|
||||
Tcl_Token *tokenPtr, *testTokenPtr;
|
||||
int jumpIndex = 0; /* Avoid compiler warning. */
|
||||
int jumpFalseDist, numWords, wordIdx, numBytes, j, code;
|
||||
int numWords, wordIdx, numBytes, j, code;
|
||||
const char *word;
|
||||
int realCond = 1; /* Set to 0 for static conditions:
|
||||
* "if 0 {..}" */
|
||||
@@ -286,7 +286,7 @@ TclCompileIfCmd(
|
||||
}
|
||||
jumpIndex = jumpFalseFixupArray.next;
|
||||
jumpFalseFixupArray.next++;
|
||||
TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,
|
||||
TclEmitForwardJump(envPtr, JUMP_FALSE,
|
||||
jumpFalseFixupArray.fixup+jumpIndex);
|
||||
}
|
||||
code = TCL_OK;
|
||||
@@ -333,7 +333,7 @@ TclCompileIfCmd(
|
||||
TclExpandJumpFixupArray(&jumpEndFixupArray);
|
||||
}
|
||||
jumpEndFixupArray.next++;
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
|
||||
TclEmitForwardJump(envPtr, JUMP,
|
||||
jumpEndFixupArray.fixup+jumpIndex);
|
||||
|
||||
/*
|
||||
@@ -345,15 +345,7 @@ TclCompileIfCmd(
|
||||
*/
|
||||
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
if (TclFixupForwardJumpToHere(envPtr,
|
||||
jumpFalseFixupArray.fixup+jumpIndex, 120)) {
|
||||
/*
|
||||
* Adjust the code offset for the proceeding jump to the end
|
||||
* of the "if" command.
|
||||
*/
|
||||
|
||||
jumpEndFixupArray.fixup[jumpIndex].codeOffset += 3;
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, jumpFalseFixupArray.fixup[jumpIndex]);
|
||||
} else if (boolVal) {
|
||||
/*
|
||||
* We were processing an "if 1 {...}"; stop compiling scripts.
|
||||
@@ -428,29 +420,7 @@ TclCompileIfCmd(
|
||||
|
||||
for (j = jumpEndFixupArray.next; j > 0; j--) {
|
||||
jumpIndex = (j - 1); /* i.e. process the closest jump first. */
|
||||
if (TclFixupForwardJumpToHere(envPtr,
|
||||
jumpEndFixupArray.fixup+jumpIndex, 127)) {
|
||||
/*
|
||||
* Adjust the immediately preceeding "ifFalse" jump. We moved it's
|
||||
* target (just after this jump) down three bytes.
|
||||
*/
|
||||
|
||||
unsigned char *ifFalsePc = envPtr->codeStart
|
||||
+ jumpFalseFixupArray.fixup[jumpIndex].codeOffset;
|
||||
unsigned char opCode = *ifFalsePc;
|
||||
|
||||
if (opCode == INST_JUMP_FALSE1) {
|
||||
jumpFalseDist = TclGetInt1AtPtr(ifFalsePc + 1);
|
||||
jumpFalseDist += 3;
|
||||
TclStoreInt1AtPtr(jumpFalseDist, (ifFalsePc + 1));
|
||||
} else if (opCode == INST_JUMP_FALSE4) {
|
||||
jumpFalseDist = TclGetInt4AtPtr(ifFalsePc + 1);
|
||||
jumpFalseDist += 3;
|
||||
TclStoreInt4AtPtr(jumpFalseDist, (ifFalsePc + 1));
|
||||
} else {
|
||||
Tcl_Panic("TclCompileIfCmd: unexpected opcode \"%d\" updating ifFalse jump", (int) opCode);
|
||||
}
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, jumpEndFixupArray.fixup[jumpIndex]);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -644,7 +614,7 @@ TclCompileInfoCommandsCmd(
|
||||
TclEmitOpcode( INST_RESOLVE_COMMAND, envPtr);
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_STR_LEN, envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_FALSE1, 7, envPtr);
|
||||
TclEmitInstInt4( INST_JUMP_FALSE4, 10, envPtr);
|
||||
TclEmitInstInt4( INST_LIST, 1, envPtr);
|
||||
return TCL_OK;
|
||||
|
||||
@@ -1983,7 +1953,7 @@ TclCompileNamespaceQualifiersCmd(
|
||||
PushStringLiteral(envPtr, ":");
|
||||
TclEmitOpcode( INST_STR_EQ, envPtr);
|
||||
off = off - CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_TRUE1, off, envPtr);
|
||||
TclEmitInstInt4( INST_JUMP_TRUE4, off, envPtr);
|
||||
TclEmitOpcode( INST_STR_RANGE, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1999,7 +1969,7 @@ TclCompileNamespaceTailCmd(
|
||||
{
|
||||
Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
JumpFixup jumpFixup;
|
||||
int jumpFixup;
|
||||
|
||||
if (parsePtr->numWords != 2) {
|
||||
return TCL_ERROR;
|
||||
@@ -2016,10 +1986,10 @@ TclCompileNamespaceTailCmd(
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
PushStringLiteral(envPtr, "0");
|
||||
TclEmitOpcode( INST_GE, envPtr);
|
||||
TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP_FALSE, &jumpFixup);
|
||||
PushStringLiteral(envPtr, "2");
|
||||
TclEmitOpcode( INST_ADD, envPtr);
|
||||
TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127);
|
||||
TclFixupForwardJumpToHere(envPtr, jumpFixup);
|
||||
PushStringLiteral(envPtr, "end");
|
||||
TclEmitOpcode( INST_STR_RANGE, envPtr);
|
||||
return TCL_OK;
|
||||
|
||||
+57
-119
@@ -226,10 +226,6 @@ TclCompileSetCmd(
|
||||
if (localIndex < 0) {
|
||||
TclEmitOpcode((isAssignment?
|
||||
INST_STORE_STK : INST_LOAD_STK), envPtr);
|
||||
} else if (localIndex <= 255) {
|
||||
TclEmitInstInt1((isAssignment?
|
||||
INST_STORE_SCALAR1 : INST_LOAD_SCALAR1),
|
||||
localIndex, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4((isAssignment?
|
||||
INST_STORE_SCALAR4 : INST_LOAD_SCALAR4),
|
||||
@@ -239,10 +235,6 @@ TclCompileSetCmd(
|
||||
if (localIndex < 0) {
|
||||
TclEmitOpcode((isAssignment?
|
||||
INST_STORE_ARRAY_STK : INST_LOAD_ARRAY_STK), envPtr);
|
||||
} else if (localIndex <= 255) {
|
||||
TclEmitInstInt1((isAssignment?
|
||||
INST_STORE_ARRAY1 : INST_LOAD_ARRAY1),
|
||||
localIndex, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4((isAssignment?
|
||||
INST_STORE_ARRAY4 : INST_LOAD_ARRAY4),
|
||||
@@ -1451,8 +1443,8 @@ TclSubstCompile(
|
||||
tokenPtr < endTokenPtr; tokenPtr = TokenAfter(tokenPtr)) {
|
||||
int length, literal, catchRange, breakJump;
|
||||
char buf[TCL_UTF_MAX];
|
||||
JumpFixup startFixup, okFixup, returnFixup, breakFixup;
|
||||
JumpFixup continueFixup, otherFixup, endFixup;
|
||||
int startFixup, okFixup, returnFixup, breakFixup;
|
||||
int continueFixup, otherFixup, endFixup;
|
||||
|
||||
switch (tokenPtr->type) {
|
||||
case TCL_TOKEN_TEXT:
|
||||
@@ -1511,17 +1503,14 @@ TclSubstCompile(
|
||||
|
||||
if (breakOffset == 0) {
|
||||
/* Jump to the start (jump over the jump to end) */
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &startFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP, &startFixup);
|
||||
|
||||
/* Jump to the end (all BREAKs land here) */
|
||||
breakOffset = CurrentOffset(envPtr);
|
||||
TclEmitInstInt4(INST_JUMP4, 0, envPtr);
|
||||
|
||||
/* Start */
|
||||
if (TclFixupForwardJumpToHere(envPtr, &startFixup, 127)) {
|
||||
Tcl_Panic("TclCompileSubstCmd: bad start jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - startFixup.codeOffset));
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, startFixup);
|
||||
}
|
||||
|
||||
envPtr->line = bline;
|
||||
@@ -1548,7 +1537,7 @@ TclSubstCompile(
|
||||
|
||||
/* Substitution produced TCL_OK */
|
||||
OP( END_CATCH);
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &okFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP, &okFixup);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
|
||||
/* Exceptional return codes processed here */
|
||||
@@ -1561,57 +1550,41 @@ TclSubstCompile(
|
||||
|
||||
/* ERROR -> reraise it; NB: can't require BREAK/CONTINUE handling */
|
||||
OP( RETURN_STK);
|
||||
OP( NOP);
|
||||
OP( DONE); /* unreachable; a NOP that cannot be removed! */
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
|
||||
/* RETURN */
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &returnFixup);
|
||||
TclEmitForwardJump1(envPtr, JUMP, &returnFixup);
|
||||
|
||||
/* BREAK */
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &breakFixup);
|
||||
TclEmitForwardJump1(envPtr, JUMP, &breakFixup);
|
||||
|
||||
/* CONTINUE */
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &continueFixup);
|
||||
TclEmitForwardJump1(envPtr, JUMP, &continueFixup);
|
||||
|
||||
/* OTHER */
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &otherFixup);
|
||||
TclEmitForwardJump1(envPtr, JUMP, &otherFixup);
|
||||
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
/* BREAK destination */
|
||||
if (TclFixupForwardJumpToHere(envPtr, &breakFixup, 127)) {
|
||||
Tcl_Panic("TclCompileSubstCmd: bad break jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - breakFixup.codeOffset));
|
||||
}
|
||||
TclFixupForwardJumpToHere1(envPtr, breakFixup);
|
||||
OP( POP);
|
||||
OP( POP);
|
||||
|
||||
breakJump = CurrentOffset(envPtr) - breakOffset;
|
||||
if (breakJump > 127) {
|
||||
OP4(JUMP4, -breakJump);
|
||||
} else {
|
||||
OP1(JUMP1, -breakJump);
|
||||
}
|
||||
OP4(JUMP4, -breakJump);
|
||||
|
||||
TclAdjustStackDepth(2, envPtr);
|
||||
/* CONTINUE destination */
|
||||
if (TclFixupForwardJumpToHere(envPtr, &continueFixup, 127)) {
|
||||
Tcl_Panic("TclCompileSubstCmd: bad continue jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - continueFixup.codeOffset));
|
||||
}
|
||||
TclFixupForwardJumpToHere1(envPtr, continueFixup);
|
||||
OP( POP);
|
||||
OP( POP);
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &endFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP, &endFixup);
|
||||
|
||||
TclAdjustStackDepth(2, envPtr);
|
||||
/* RETURN + other destination */
|
||||
if (TclFixupForwardJumpToHere(envPtr, &returnFixup, 127)) {
|
||||
Tcl_Panic("TclCompileSubstCmd: bad return jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - returnFixup.codeOffset));
|
||||
}
|
||||
if (TclFixupForwardJumpToHere(envPtr, &otherFixup, 127)) {
|
||||
Tcl_Panic("TclCompileSubstCmd: bad other jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - otherFixup.codeOffset));
|
||||
}
|
||||
|
||||
TclFixupForwardJumpToHere1(envPtr, returnFixup);
|
||||
TclFixupForwardJumpToHere1(envPtr, otherFixup);
|
||||
/*
|
||||
* Pull the result to top of stack, discard options dict.
|
||||
*/
|
||||
@@ -1620,20 +1593,14 @@ TclSubstCompile(
|
||||
OP( POP);
|
||||
|
||||
/* OK destination */
|
||||
if (TclFixupForwardJumpToHere(envPtr, &okFixup, 127)) {
|
||||
Tcl_Panic("TclCompileSubstCmd: bad ok jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - okFixup.codeOffset));
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, okFixup);
|
||||
if (count > 1) {
|
||||
OP1(STR_CONCAT1, count);
|
||||
count = 1;
|
||||
}
|
||||
|
||||
/* CONTINUE jump to here */
|
||||
if (TclFixupForwardJumpToHere(envPtr, &endFixup, 127)) {
|
||||
Tcl_Panic("TclCompileSubstCmd: bad end jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - endFixup.codeOffset));
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, endFixup);
|
||||
bline = envPtr->line;
|
||||
}
|
||||
|
||||
@@ -2027,7 +1994,7 @@ IssueSwitchChainedTests(
|
||||
enum {Switch_Exact, Switch_Glob, Switch_Regexp};
|
||||
int foundDefault; /* Flag to indicate whether a "default" clause
|
||||
* is present. */
|
||||
JumpFixup *fixupArray; /* Array of forward-jump fixup records. */
|
||||
int *fixupArray; /* Array of forward-jump fixup records. */
|
||||
int *fixupTargetArray; /* Array of places for fixups to point at. */
|
||||
int fixupCount; /* Number of places to fix up. */
|
||||
int contFixIndex; /* Where the first of the jumps due to a group
|
||||
@@ -2045,7 +2012,7 @@ IssueSwitchChainedTests(
|
||||
|
||||
contFixIndex = -1;
|
||||
contFixCount = 0;
|
||||
fixupArray = TclStackAlloc(interp, sizeof(JumpFixup) * numBodyTokens);
|
||||
fixupArray = TclStackAlloc(interp, sizeof(int) * numBodyTokens);
|
||||
fixupTargetArray = TclStackAlloc(interp, sizeof(int) * numBodyTokens);
|
||||
memset(fixupTargetArray, 0, numBodyTokens * sizeof(int));
|
||||
fixupCount = 0;
|
||||
@@ -2140,14 +2107,14 @@ IssueSwitchChainedTests(
|
||||
contFixIndex = fixupCount;
|
||||
contFixCount = 0;
|
||||
}
|
||||
TclEmitForwardJump(envPtr, TCL_TRUE_JUMP,
|
||||
TclEmitForwardJump(envPtr, JUMP_TRUE,
|
||||
&fixupArray[contFixIndex+contFixCount]);
|
||||
fixupCount++;
|
||||
contFixCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,
|
||||
TclEmitForwardJump(envPtr, JUMP_FALSE,
|
||||
&fixupArray[fixupCount]);
|
||||
nextArmFixupIndex = fixupCount;
|
||||
fixupCount++;
|
||||
@@ -2193,7 +2160,7 @@ IssueSwitchChainedTests(
|
||||
TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
|
||||
|
||||
if (!foundDefault) {
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
|
||||
TclEmitForwardJump(envPtr, JUMP,
|
||||
&fixupArray[fixupCount]);
|
||||
fixupCount++;
|
||||
fixupTargetArray[nextArmFixupIndex] = CurrentOffset(envPtr);
|
||||
@@ -2219,30 +2186,13 @@ IssueSwitchChainedTests(
|
||||
|
||||
for (i=0 ; i<fixupCount ; i++) {
|
||||
if (fixupTargetArray[i] == 0) {
|
||||
fixupTargetArray[i] = envPtr->codeNext-envPtr->codeStart;
|
||||
TclFixupForwardJumpToHere(envPtr, fixupArray[i]);
|
||||
} else {
|
||||
TclFixupForwardJump(envPtr, fixupArray[i],
|
||||
fixupTargetArray[i] - fixupArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now scan backwards over all the jumps (all of which are forward jumps)
|
||||
* doing each one. When we do one and there is a size changes, we must
|
||||
* scan back over all the previous ones and see if they need adjusting
|
||||
* before proceeding with further jump fixups (the interleaved nature of
|
||||
* all the jumps makes this impossible to do without nested loops).
|
||||
*/
|
||||
|
||||
for (i=fixupCount-1 ; i>=0 ; i--) {
|
||||
if (TclFixupForwardJump(envPtr, &fixupArray[i],
|
||||
fixupTargetArray[i] - fixupArray[i].codeOffset, 127)) {
|
||||
int j;
|
||||
|
||||
for (j=i-1 ; j>=0 ; j--) {
|
||||
if (fixupTargetArray[j] > fixupArray[i].codeOffset) {
|
||||
fixupTargetArray[j] += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TclStackFree(interp, fixupTargetArray);
|
||||
TclStackFree(interp, fixupArray);
|
||||
}
|
||||
@@ -2675,7 +2625,7 @@ TclCompileThrowCmd(
|
||||
OP4( REVERSE, 3);
|
||||
OP( DUP);
|
||||
OP( LIST_LENGTH);
|
||||
OP1( JUMP_FALSE1, 16);
|
||||
OP4( JUMP_FALSE4, 19);
|
||||
OP4( LIST, 2);
|
||||
OP44( RETURN_IMM, TCL_ERROR, 0);
|
||||
TclAdjustStackDepth(2, envPtr);
|
||||
@@ -2996,7 +2946,7 @@ IssueTryClausesInstructions(
|
||||
} else {
|
||||
PUSH( "0");
|
||||
OP4( REVERSE, 2);
|
||||
OP1( JUMP1, 4);
|
||||
OP4( JUMP4, 7);
|
||||
TclAdjustStackDepth(-2, envPtr);
|
||||
}
|
||||
ExceptionRangeTarget(envPtr, range, catchOffset);
|
||||
@@ -3098,7 +3048,7 @@ IssueTryClausesInstructions(
|
||||
OP( END_CATCH);
|
||||
PUSH( "1");
|
||||
OP( EQ);
|
||||
JUMP1( JUMP_FALSE, dontChangeOptions);
|
||||
JUMP4( JUMP_FALSE, dontChangeOptions);
|
||||
LOAD( optionsVar);
|
||||
OP4( REVERSE, 2);
|
||||
STORE( optionsVar);
|
||||
@@ -3107,7 +3057,7 @@ IssueTryClausesInstructions(
|
||||
OP4( REVERSE, 2);
|
||||
OP44( DICT_SET, 1, optionsVar);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
FIXJUMP1( dontChangeOptions);
|
||||
FIXJUMP4( dontChangeOptions);
|
||||
OP4( REVERSE, 2);
|
||||
INVOKE( RETURN_STK);
|
||||
}
|
||||
@@ -3208,7 +3158,7 @@ IssueTryClausesFinallyInstructions(
|
||||
} else {
|
||||
PUSH( "0");
|
||||
OP4( REVERSE, 2);
|
||||
OP1( JUMP1, 4);
|
||||
OP4( JUMP4, 7);
|
||||
TclAdjustStackDepth(-2, envPtr);
|
||||
}
|
||||
ExceptionRangeTarget(envPtr, range, catchOffset);
|
||||
@@ -3314,7 +3264,7 @@ IssueTryClausesFinallyInstructions(
|
||||
|
||||
if (forwardsNeedFixing) {
|
||||
forwardsNeedFixing = 0;
|
||||
OP1( JUMP1, 7);
|
||||
OP4( JUMP4, 10);
|
||||
for (j=0 ; j<i ; j++) {
|
||||
if (forwardsToFix[j] == -1) {
|
||||
continue;
|
||||
@@ -3329,7 +3279,7 @@ IssueTryClausesFinallyInstructions(
|
||||
PUSH( "0");
|
||||
OP( PUSH_RETURN_OPTIONS);
|
||||
OP4( REVERSE, 3);
|
||||
OP1( JUMP1, 5);
|
||||
OP4( JUMP4, 8);
|
||||
TclAdjustStackDepth(-3, envPtr);
|
||||
forwardsToFix[i] = -1;
|
||||
|
||||
@@ -3350,7 +3300,7 @@ IssueTryClausesFinallyInstructions(
|
||||
OP( POP);
|
||||
PUSH( "1");
|
||||
OP( EQ);
|
||||
JUMP1( JUMP_FALSE, noTrapError);
|
||||
JUMP4( JUMP_FALSE, noTrapError);
|
||||
LOAD( optionsVar);
|
||||
PUSH( "-during");
|
||||
OP4( REVERSE, 3);
|
||||
@@ -3358,10 +3308,10 @@ IssueTryClausesFinallyInstructions(
|
||||
OP( POP);
|
||||
OP44( DICT_SET, 1, optionsVar);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
JUMP1( JUMP, trapError);
|
||||
FIXJUMP1( noTrapError);
|
||||
JUMP4( JUMP, trapError);
|
||||
FIXJUMP4( noTrapError);
|
||||
STORE( optionsVar);
|
||||
FIXJUMP1( trapError);
|
||||
FIXJUMP4( trapError);
|
||||
/* Skip POP at end; can clean up with subsequent POP */
|
||||
if (i+1 < numHandlers) {
|
||||
OP( POP);
|
||||
@@ -3409,7 +3359,7 @@ IssueTryClausesFinallyInstructions(
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
OP( END_CATCH);
|
||||
OP( POP);
|
||||
JUMP1( JUMP, finalOK);
|
||||
JUMP4( JUMP, finalOK);
|
||||
ExceptionRangeTarget(envPtr, range, catchOffset);
|
||||
OP( PUSH_RESULT);
|
||||
OP( PUSH_RETURN_OPTIONS);
|
||||
@@ -3417,7 +3367,7 @@ IssueTryClausesFinallyInstructions(
|
||||
OP( END_CATCH);
|
||||
PUSH( "1");
|
||||
OP( EQ);
|
||||
JUMP1( JUMP_FALSE, noFinalError);
|
||||
JUMP4( JUMP_FALSE, noFinalError);
|
||||
LOAD( optionsVar);
|
||||
PUSH( "-during");
|
||||
OP4( REVERSE, 3);
|
||||
@@ -3426,15 +3376,15 @@ IssueTryClausesFinallyInstructions(
|
||||
OP44( DICT_SET, 1, optionsVar);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
OP( POP);
|
||||
JUMP1( JUMP, finalError);
|
||||
JUMP4( JUMP, finalError);
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
FIXJUMP1( noFinalError);
|
||||
FIXJUMP4( noFinalError);
|
||||
STORE( optionsVar);
|
||||
OP( POP);
|
||||
FIXJUMP1( finalError);
|
||||
FIXJUMP4( finalError);
|
||||
STORE( resultVar);
|
||||
OP( POP);
|
||||
FIXJUMP1( finalOK);
|
||||
FIXJUMP4( finalOK);
|
||||
LOAD( optionsVar);
|
||||
LOAD( resultVar);
|
||||
INVOKE( RETURN_STK);
|
||||
@@ -3462,7 +3412,7 @@ IssueTryFinallyInstructions(
|
||||
ExceptionRangeStarts(envPtr, range);
|
||||
BODY( bodyToken, 1);
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
OP1( JUMP1, 3);
|
||||
OP4( JUMP4, 6);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
ExceptionRangeTarget(envPtr, range, catchOffset);
|
||||
OP( PUSH_RESULT);
|
||||
@@ -3476,7 +3426,7 @@ IssueTryFinallyInstructions(
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
OP( END_CATCH);
|
||||
OP( POP);
|
||||
JUMP1( JUMP, jumpOK);
|
||||
JUMP4( JUMP, jumpOK);
|
||||
ExceptionRangeTarget(envPtr, range, catchOffset);
|
||||
OP( PUSH_RESULT);
|
||||
OP( PUSH_RETURN_OPTIONS);
|
||||
@@ -3484,17 +3434,17 @@ IssueTryFinallyInstructions(
|
||||
OP( END_CATCH);
|
||||
PUSH( "1");
|
||||
OP( EQ);
|
||||
JUMP1( JUMP_FALSE, jumpSplice);
|
||||
JUMP4( JUMP_FALSE, jumpSplice);
|
||||
PUSH( "-during");
|
||||
OP4( OVER, 3);
|
||||
OP4( LIST, 2);
|
||||
OP( LIST_CONCAT);
|
||||
FIXJUMP1( jumpSplice);
|
||||
FIXJUMP4( jumpSplice);
|
||||
OP4( REVERSE, 4);
|
||||
OP( POP);
|
||||
OP( POP);
|
||||
OP1( JUMP1, 7);
|
||||
FIXJUMP1( jumpOK);
|
||||
OP4( JUMP4, 10);
|
||||
FIXJUMP4( jumpOK);
|
||||
OP4( REVERSE, 2);
|
||||
INVOKE( RETURN_STK);
|
||||
return TCL_OK;
|
||||
@@ -3666,7 +3616,7 @@ TclCompileWhileCmd(
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
Tcl_Token *testTokenPtr, *bodyTokenPtr;
|
||||
JumpFixup jumpEvalCondFixup;
|
||||
int jumpEvalCondFixup;
|
||||
int testCodeOffset, bodyCodeOffset, jumpDist, range, code, boolVal;
|
||||
int loopMayEnd = 1; /* This is set to 0 if it is recognized as an
|
||||
* infinite loop. */
|
||||
@@ -3742,8 +3692,7 @@ TclCompileWhileCmd(
|
||||
*/
|
||||
|
||||
if (loopMayEnd) {
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
|
||||
&jumpEvalCondFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP, &jumpEvalCondFixup);
|
||||
testCodeOffset = 0; /* Avoid compiler warning. */
|
||||
} else {
|
||||
/*
|
||||
@@ -3775,27 +3724,16 @@ TclCompileWhileCmd(
|
||||
|
||||
if (loopMayEnd) {
|
||||
testCodeOffset = CurrentOffset(envPtr);
|
||||
jumpDist = testCodeOffset - jumpEvalCondFixup.codeOffset;
|
||||
if (TclFixupForwardJump(envPtr, &jumpEvalCondFixup, jumpDist, 127)) {
|
||||
bodyCodeOffset += 3;
|
||||
testCodeOffset += 3;
|
||||
}
|
||||
jumpDist = testCodeOffset - jumpEvalCondFixup;
|
||||
TclFixupForwardJump(envPtr, jumpEvalCondFixup, jumpDist);
|
||||
SetLineInformation(1);
|
||||
TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
|
||||
|
||||
jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
|
||||
if (jumpDist > 127) {
|
||||
TclEmitInstInt4(INST_JUMP_TRUE4, -jumpDist, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt1(INST_JUMP_TRUE1, -jumpDist, envPtr);
|
||||
}
|
||||
TclEmitInstInt4(INST_JUMP_TRUE4, -jumpDist, envPtr);
|
||||
} else {
|
||||
jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
|
||||
if (jumpDist > 127) {
|
||||
TclEmitInstInt4(INST_JUMP4, -jumpDist, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt1(INST_JUMP1, -jumpDist, envPtr);
|
||||
}
|
||||
TclEmitInstInt4(INST_JUMP4, -jumpDist, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+32
-23
@@ -487,12 +487,21 @@ static const unsigned char Lexeme[] = {
|
||||
*/
|
||||
|
||||
typedef struct JumpList {
|
||||
JumpFixup jump; /* Pass this argument to matching calls of
|
||||
int jump; /* Pass this argument to matching calls of
|
||||
* TclEmitForwardJump() and
|
||||
* TclFixupForwardJump(). */
|
||||
struct JumpList *next; /* Point to next item on the stack */
|
||||
} JumpList;
|
||||
|
||||
/*
|
||||
* Macro to convert a jump to a different type
|
||||
*/
|
||||
|
||||
#define CONVERT_JUMP(which, type) \
|
||||
TclUpdateInstInt4AtPc(INST_##type##4, 0, \
|
||||
envPtr->codeStart + (which))
|
||||
|
||||
|
||||
/*
|
||||
* Declarations for local functions to this file:
|
||||
*/
|
||||
@@ -2290,17 +2299,16 @@ CompileExprTree(
|
||||
newJump = TclStackAlloc(interp, sizeof(JumpList));
|
||||
newJump->next = jumpPtr;
|
||||
jumpPtr = newJump;
|
||||
TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpPtr->jump);
|
||||
TclEmitForwardJump(envPtr, JUMP_FALSE, &jumpPtr->jump);
|
||||
break;
|
||||
case COLON:
|
||||
newJump = TclStackAlloc(interp, sizeof(JumpList));
|
||||
newJump->next = jumpPtr;
|
||||
jumpPtr = newJump;
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
|
||||
&jumpPtr->jump);
|
||||
TclEmitForwardJump(envPtr, JUMP, &jumpPtr->jump);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
if (convert) {
|
||||
jumpPtr->jump.jumpType = TCL_TRUE_JUMP;
|
||||
CONVERT_JUMP(jumpPtr->jump, JUMP_TRUE);
|
||||
}
|
||||
convert = 1;
|
||||
break;
|
||||
@@ -2309,8 +2317,11 @@ CompileExprTree(
|
||||
newJump = TclStackAlloc(interp, sizeof(JumpList));
|
||||
newJump->next = jumpPtr;
|
||||
jumpPtr = newJump;
|
||||
TclEmitForwardJump(envPtr, (nodePtr->lexeme == AND)
|
||||
? TCL_FALSE_JUMP : TCL_TRUE_JUMP, &jumpPtr->jump);
|
||||
if (nodePtr->lexeme == AND) {
|
||||
TclEmitForwardJump(envPtr, JUMP_FALSE, &jumpPtr->jump);
|
||||
} else {
|
||||
TclEmitForwardJump(envPtr, JUMP_TRUE, &jumpPtr->jump);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -2355,19 +2366,19 @@ CompileExprTree(
|
||||
break;
|
||||
case COLON:
|
||||
CLANG_ASSERT(jumpPtr);
|
||||
if (jumpPtr->jump.jumpType == TCL_TRUE_JUMP) {
|
||||
jumpPtr->jump.jumpType = TCL_UNCONDITIONAL_JUMP;
|
||||
if (*(envPtr->codeStart + jumpPtr->jump) ==
|
||||
INST_JUMP_TRUE4) {
|
||||
CONVERT_JUMP(jumpPtr->jump, JUMP);
|
||||
convert = 1;
|
||||
}
|
||||
target = jumpPtr->jump.codeOffset + 2;
|
||||
if (TclFixupForwardJumpToHere(envPtr, &jumpPtr->jump, 127)) {
|
||||
target += 3;
|
||||
}
|
||||
target = jumpPtr->jump + 5;
|
||||
TclFixupForwardJumpToHere(envPtr, jumpPtr->jump);
|
||||
|
||||
freePtr = jumpPtr;
|
||||
jumpPtr = jumpPtr->next;
|
||||
TclStackFree(interp, freePtr);
|
||||
TclFixupForwardJump(envPtr, &jumpPtr->jump,
|
||||
target - jumpPtr->jump.codeOffset, 127);
|
||||
TclFixupForwardJump(envPtr, jumpPtr->jump,
|
||||
target - jumpPtr->jump);
|
||||
|
||||
freePtr = jumpPtr;
|
||||
jumpPtr = jumpPtr->next;
|
||||
@@ -2377,21 +2388,19 @@ CompileExprTree(
|
||||
case OR:
|
||||
CLANG_ASSERT(jumpPtr);
|
||||
pc1 = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1((nodePtr->lexeme == AND) ? INST_JUMP_FALSE1
|
||||
: INST_JUMP_TRUE1, 0, envPtr);
|
||||
TclEmitInstInt4((nodePtr->lexeme == AND) ? INST_JUMP_FALSE4
|
||||
: INST_JUMP_TRUE4, 0, envPtr);
|
||||
TclEmitPush(TclRegisterNewLiteral(envPtr,
|
||||
(nodePtr->lexeme == AND) ? "1" : "0", 1), envPtr);
|
||||
pc2 = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1(INST_JUMP1, 0, envPtr);
|
||||
TclEmitInstInt4(INST_JUMP4, 0, envPtr);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - pc1,
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr) - pc1,
|
||||
envPtr->codeStart + pc1 + 1);
|
||||
if (TclFixupForwardJumpToHere(envPtr, &jumpPtr->jump, 127)) {
|
||||
pc2 += 3;
|
||||
}
|
||||
TclFixupForwardJumpToHere(envPtr, jumpPtr->jump);
|
||||
TclEmitPush(TclRegisterNewLiteral(envPtr,
|
||||
(nodePtr->lexeme == AND) ? "0" : "1", 1), envPtr);
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - pc2,
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr) - pc2,
|
||||
envPtr->codeStart + pc2 + 1);
|
||||
convert = 0;
|
||||
freePtr = jumpPtr;
|
||||
|
||||
+12
-204
@@ -852,6 +852,11 @@ TclSetByteCodeFromAny(
|
||||
/*
|
||||
* Apply some peephole optimizations that can cross specific/generic
|
||||
* instruction generator boundaries.
|
||||
*
|
||||
* TODO: should this go to InitByteCode instead? Compilations from
|
||||
* CompileExprObj, ExecConstantExprTree, CompileAssembleObj currently skip
|
||||
* the optimization ... certainly OK for the last two, iffy for the
|
||||
* first?
|
||||
*/
|
||||
|
||||
if (iPtr->extra.optimizer) {
|
||||
@@ -3719,7 +3724,7 @@ TclInitJumpFixupArray(
|
||||
/* Points to the JumpFixupArray structure to
|
||||
* initialize. */
|
||||
{
|
||||
fixupArrayPtr->fixup = fixupArrayPtr->staticFixupSpace;
|
||||
fixupArrayPtr->fixup = fixupArrayPtr->staticCodeOffsets;
|
||||
fixupArrayPtr->next = 0;
|
||||
fixupArrayPtr->end = JUMPFIXUP_INIT_ENTRIES - 1;
|
||||
fixupArrayPtr->mallocedArray = 0;
|
||||
@@ -3757,9 +3762,9 @@ TclExpandJumpFixupArray(
|
||||
* fixupArrayPtr->fixupNext is equal to fixupArrayPtr->fixupEnd.
|
||||
*/
|
||||
|
||||
size_t currBytes = fixupArrayPtr->next * sizeof(JumpFixup);
|
||||
size_t currBytes = fixupArrayPtr->next * sizeof(int);
|
||||
int newElems = 2*(fixupArrayPtr->end + 1);
|
||||
size_t newBytes = newElems * sizeof(JumpFixup);
|
||||
size_t newBytes = newElems * sizeof(int);
|
||||
|
||||
if (fixupArrayPtr->mallocedArray) {
|
||||
fixupArrayPtr->fixup = ckrealloc(fixupArrayPtr->fixup, newBytes);
|
||||
@@ -3769,7 +3774,7 @@ TclExpandJumpFixupArray(
|
||||
* ckrealloc equivalent for ourselves.
|
||||
*/
|
||||
|
||||
JumpFixup *newPtr = ckalloc(newBytes);
|
||||
int *newPtr = ckalloc(newBytes);
|
||||
|
||||
memcpy(newPtr, fixupArrayPtr->fixup, currBytes);
|
||||
fixupArrayPtr->fixup = newPtr;
|
||||
@@ -3805,203 +3810,6 @@ TclFreeJumpFixupArray(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclEmitForwardJump --
|
||||
*
|
||||
* Procedure to emit a two-byte forward jump of kind "jumpType". Since
|
||||
* the jump may later have to be grown to five bytes if the jump target
|
||||
* is more than, say, 127 bytes away, this procedure also initializes a
|
||||
* JumpFixup record with information about the jump.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The JumpFixup record pointed to by "jumpFixupPtr" is initialized with
|
||||
* information needed later if the jump is to be grown. Also, a two byte
|
||||
* jump of the designated type is emitted at the current point in the
|
||||
* bytecode stream.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TclEmitForwardJump(
|
||||
CompileEnv *envPtr, /* Points to the CompileEnv structure that
|
||||
* holds the resulting instruction. */
|
||||
TclJumpType jumpType, /* Indicates the kind of jump: if true or
|
||||
* false or unconditional. */
|
||||
JumpFixup *jumpFixupPtr) /* Points to the JumpFixup structure to
|
||||
* initialize with information about this
|
||||
* forward jump. */
|
||||
{
|
||||
/*
|
||||
* Initialize the JumpFixup structure:
|
||||
* - codeOffset is offset of first byte of jump below
|
||||
* - cmdIndex is index of the command after the current one
|
||||
* - exceptIndex is the index of the first ExceptionRange after the
|
||||
* current one.
|
||||
*/
|
||||
|
||||
jumpFixupPtr->jumpType = jumpType;
|
||||
jumpFixupPtr->codeOffset = envPtr->codeNext - envPtr->codeStart;
|
||||
jumpFixupPtr->cmdIndex = envPtr->numCommands;
|
||||
jumpFixupPtr->exceptIndex = envPtr->exceptArrayNext;
|
||||
|
||||
switch (jumpType) {
|
||||
case TCL_UNCONDITIONAL_JUMP:
|
||||
TclEmitInstInt1(INST_JUMP1, 0, envPtr);
|
||||
break;
|
||||
case TCL_TRUE_JUMP:
|
||||
TclEmitInstInt1(INST_JUMP_TRUE1, 0, envPtr);
|
||||
break;
|
||||
default:
|
||||
TclEmitInstInt1(INST_JUMP_FALSE1, 0, envPtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclFixupForwardJump --
|
||||
*
|
||||
* Procedure that updates a previously-emitted forward jump to jump a
|
||||
* specified number of bytes, "jumpDist". If necessary, the jump is grown
|
||||
* from two to five bytes; this is done if the jump distance is greater
|
||||
* than "distThreshold" (normally 127 bytes). The jump is described by a
|
||||
* JumpFixup record previously initialized by TclEmitForwardJump.
|
||||
*
|
||||
* Results:
|
||||
* 1 if the jump was grown and subsequent instructions had to be moved;
|
||||
* otherwise 0. This result is returned to allow callers to update any
|
||||
* additional code offsets they may hold.
|
||||
*
|
||||
* Side effects:
|
||||
* The jump may be grown and subsequent instructions moved. If this
|
||||
* happens, the code offsets for any commands and any ExceptionRange
|
||||
* records between the jump and the current code address will be updated
|
||||
* to reflect the moved code. Also, the bytecode instruction array in the
|
||||
* CompileEnv structure may be grown and reallocated.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclFixupForwardJump(
|
||||
CompileEnv *envPtr, /* Points to the CompileEnv structure that
|
||||
* holds the resulting instruction. */
|
||||
JumpFixup *jumpFixupPtr, /* Points to the JumpFixup structure that
|
||||
* describes the forward jump. */
|
||||
int jumpDist, /* Jump distance to set in jump instr. */
|
||||
int distThreshold) /* Maximum distance before the two byte jump
|
||||
* is grown to five bytes. */
|
||||
{
|
||||
unsigned char *jumpPc, *p;
|
||||
int firstCmd, lastCmd, firstRange, lastRange, k;
|
||||
unsigned numBytes;
|
||||
|
||||
if (jumpDist <= distThreshold) {
|
||||
jumpPc = envPtr->codeStart + jumpFixupPtr->codeOffset;
|
||||
switch (jumpFixupPtr->jumpType) {
|
||||
case TCL_UNCONDITIONAL_JUMP:
|
||||
TclUpdateInstInt1AtPc(INST_JUMP1, jumpDist, jumpPc);
|
||||
break;
|
||||
case TCL_TRUE_JUMP:
|
||||
TclUpdateInstInt1AtPc(INST_JUMP_TRUE1, jumpDist, jumpPc);
|
||||
break;
|
||||
default:
|
||||
TclUpdateInstInt1AtPc(INST_JUMP_FALSE1, jumpDist, jumpPc);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We must grow the jump then move subsequent instructions down. Note that
|
||||
* if we expand the space for generated instructions, code addresses might
|
||||
* change; be careful about updating any of these addresses held in
|
||||
* variables.
|
||||
*/
|
||||
|
||||
if ((envPtr->codeNext + 3) > envPtr->codeEnd) {
|
||||
TclExpandCodeArray(envPtr);
|
||||
}
|
||||
jumpPc = envPtr->codeStart + jumpFixupPtr->codeOffset;
|
||||
numBytes = envPtr->codeNext-jumpPc-2;
|
||||
p = jumpPc+2;
|
||||
memmove(p+3, p, numBytes);
|
||||
|
||||
envPtr->codeNext += 3;
|
||||
jumpDist += 3;
|
||||
switch (jumpFixupPtr->jumpType) {
|
||||
case TCL_UNCONDITIONAL_JUMP:
|
||||
TclUpdateInstInt4AtPc(INST_JUMP4, jumpDist, jumpPc);
|
||||
break;
|
||||
case TCL_TRUE_JUMP:
|
||||
TclUpdateInstInt4AtPc(INST_JUMP_TRUE4, jumpDist, jumpPc);
|
||||
break;
|
||||
default:
|
||||
TclUpdateInstInt4AtPc(INST_JUMP_FALSE4, jumpDist, jumpPc);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust the code offsets for any commands and any ExceptionRange records
|
||||
* between the jump and the current code address.
|
||||
*/
|
||||
|
||||
firstCmd = jumpFixupPtr->cmdIndex;
|
||||
lastCmd = envPtr->numCommands - 1;
|
||||
if (firstCmd < lastCmd) {
|
||||
for (k = firstCmd; k <= lastCmd; k++) {
|
||||
envPtr->cmdMapPtr[k].codeOffset += 3;
|
||||
}
|
||||
}
|
||||
|
||||
firstRange = jumpFixupPtr->exceptIndex;
|
||||
lastRange = envPtr->exceptArrayNext - 1;
|
||||
for (k = firstRange; k <= lastRange; k++) {
|
||||
ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[k];
|
||||
|
||||
rangePtr->codeOffset += 3;
|
||||
switch (rangePtr->type) {
|
||||
case LOOP_EXCEPTION_RANGE:
|
||||
rangePtr->breakOffset += 3;
|
||||
if (rangePtr->continueOffset != -1) {
|
||||
rangePtr->continueOffset += 3;
|
||||
}
|
||||
break;
|
||||
case CATCH_EXCEPTION_RANGE:
|
||||
rangePtr->catchOffset += 3;
|
||||
break;
|
||||
default:
|
||||
Tcl_Panic("TclFixupForwardJump: bad ExceptionRange type %d",
|
||||
rangePtr->type);
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0 ; k < envPtr->exceptArrayNext ; k++) {
|
||||
ExceptionAux *auxPtr = &envPtr->exceptAuxArrayPtr[k];
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<auxPtr->numBreakTargets ; i++) {
|
||||
if (jumpFixupPtr->codeOffset < auxPtr->breakTargets[i]) {
|
||||
auxPtr->breakTargets[i] += 3;
|
||||
}
|
||||
}
|
||||
for (i=0 ; i<auxPtr->numContinueTargets ; i++) {
|
||||
if (jumpFixupPtr->codeOffset < auxPtr->continueTargets[i]) {
|
||||
auxPtr->continueTargets[i] += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1; /* the jump was grown */
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -4147,7 +3955,7 @@ TclEmitInvoke(
|
||||
if (auxBreakPtr != NULL || auxContinuePtr != NULL) {
|
||||
int savedStackDepth = envPtr->currStackDepth;
|
||||
int savedExpandCount = envPtr->expandCount;
|
||||
JumpFixup nonTrapFixup;
|
||||
int nonTrapFixup;
|
||||
|
||||
if (auxBreakPtr != NULL) {
|
||||
auxBreakPtr = envPtr->exceptAuxArrayPtr + breakRange;
|
||||
@@ -4157,7 +3965,7 @@ TclEmitInvoke(
|
||||
}
|
||||
|
||||
ExceptionRangeEnds(envPtr, loopRange);
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &nonTrapFixup);
|
||||
TclEmitForwardJump(envPtr, JUMP, &nonTrapFixup);
|
||||
|
||||
/*
|
||||
* Careful! When generating these stack unwinding sequences, the depth
|
||||
@@ -4190,7 +3998,7 @@ TclEmitInvoke(
|
||||
}
|
||||
|
||||
TclFinalizeLoopExceptionRange(envPtr, loopRange);
|
||||
TclFixupForwardJumpToHere(envPtr, &nonTrapFixup, 127);
|
||||
TclFixupForwardJumpToHere(envPtr, nonTrapFixup);
|
||||
}
|
||||
TclCheckStackDepth(depth+1-cleanup, envPtr);
|
||||
}
|
||||
|
||||
+29
-47
@@ -137,20 +137,14 @@ typedef struct ExceptionAux {
|
||||
* exception will be bound to. */
|
||||
int *breakTargets; /* The offsets of the INST_JUMP4 instructions
|
||||
* issued by the [break]s that we must
|
||||
* update. Note that resizing a jump (via
|
||||
* TclFixupForwardJump) can cause the contents
|
||||
* of this array to be updated. When
|
||||
* numBreakTargets==0, this is NULL. */
|
||||
* update. NULL when numBreakTargets==0 */
|
||||
int allocBreakTargets; /* The size of the breakTargets array. */
|
||||
int numContinueTargets; /* The number of [continue]s that want to be
|
||||
* targeted to the place where this loop
|
||||
* exception will be bound to. */
|
||||
int *continueTargets; /* The offsets of the INST_JUMP4 instructions
|
||||
* issued by the [continue]s that we must
|
||||
* update. Note that resizing a jump (via
|
||||
* TclFixupForwardJump) can cause the contents
|
||||
* of this array to be updated. When
|
||||
* numContinueTargets==0, this is NULL. */
|
||||
* update. NULL when numContinueTargets==0 */
|
||||
int allocContinueTargets; /* The size of the continueTargets array. */
|
||||
} ExceptionAux;
|
||||
|
||||
@@ -920,38 +914,15 @@ MODULE_SCOPE StringClassDesc const tclStringClassTable[];
|
||||
* commands between the jump and the target.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
TCL_UNCONDITIONAL_JUMP,
|
||||
TCL_TRUE_JUMP,
|
||||
TCL_FALSE_JUMP
|
||||
} TclJumpType;
|
||||
|
||||
typedef struct JumpFixup {
|
||||
TclJumpType jumpType; /* Indicates the kind of jump. */
|
||||
int codeOffset; /* Offset of the first byte of the one-byte
|
||||
* forward jump's code. */
|
||||
int cmdIndex; /* Index of the first command after the one
|
||||
* for which the jump was emitted. Used to
|
||||
* update the code offsets for subsequent
|
||||
* commands if the two-byte jump at jumpPc
|
||||
* must be replaced with a five-byte one. */
|
||||
int exceptIndex; /* Index of the first range entry in the
|
||||
* ExceptionRange array after the current one.
|
||||
* This field is used to adjust the code
|
||||
* offsets in subsequent ExceptionRange
|
||||
* records when a jump is grown from 2 bytes
|
||||
* to 5 bytes. */
|
||||
} JumpFixup;
|
||||
|
||||
#define JUMPFIXUP_INIT_ENTRIES 10
|
||||
|
||||
typedef struct JumpFixupArray {
|
||||
JumpFixup *fixup; /* Points to start of jump fixup array. */
|
||||
int *fixup; /* Points to start of codeOffset array. */
|
||||
int next; /* Index of next free array entry. */
|
||||
int end; /* Index of last usable entry in array. */
|
||||
int mallocedArray; /* 1 if array was expanded and fixups points
|
||||
* into the heap, else 0. */
|
||||
JumpFixup staticFixupSpace[JUMPFIXUP_INIT_ENTRIES];
|
||||
int staticCodeOffsets[JUMPFIXUP_INIT_ENTRIES];
|
||||
/* Initial storage for jump fixup array. */
|
||||
} JumpFixupArray;
|
||||
|
||||
@@ -1114,8 +1085,6 @@ MODULE_SCOPE Tcl_Obj * TclCreateLiteral(Interp *iPtr, char *bytes,
|
||||
MODULE_SCOPE void TclDeleteExecEnv(ExecEnv *eePtr);
|
||||
MODULE_SCOPE void TclDeleteLiteralTable(Tcl_Interp *interp,
|
||||
LiteralTable *tablePtr);
|
||||
MODULE_SCOPE void TclEmitForwardJump(CompileEnv *envPtr,
|
||||
TclJumpType jumpType, JumpFixup *jumpFixupPtr);
|
||||
MODULE_SCOPE void TclEmitInvoke(CompileEnv *envPtr, int opcode, ...);
|
||||
MODULE_SCOPE ExceptionRange * TclGetExceptionRangeForPc(unsigned char *pc,
|
||||
int catchOnly, ByteCode *codePtr);
|
||||
@@ -1126,9 +1095,6 @@ MODULE_SCOPE Tcl_Obj * TclFetchLiteral(CompileEnv *envPtr, unsigned int index);
|
||||
MODULE_SCOPE void TclFinalizeAuxDataTypeTable(void);
|
||||
MODULE_SCOPE int TclFindCompiledLocal(const char *name, int nameChars,
|
||||
int create, CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr,
|
||||
JumpFixup *jumpFixupPtr, int jumpDist,
|
||||
int distThreshold);
|
||||
MODULE_SCOPE void TclFreeCompileEnv(CompileEnv *envPtr);
|
||||
MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr);
|
||||
MODULE_SCOPE void TclInitAuxDataTypeTable(void);
|
||||
@@ -1410,11 +1376,7 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
|
||||
#define TclEmitPush(objIndex, envPtr) \
|
||||
do { \
|
||||
register int objIndexCopy = (objIndex); \
|
||||
if (objIndexCopy <= 255) { \
|
||||
TclEmitInstInt1(INST_PUSH1, objIndexCopy, (envPtr)); \
|
||||
} else { \
|
||||
TclEmitInstInt4(INST_PUSH4, objIndexCopy, (envPtr)); \
|
||||
} \
|
||||
TclEmitInstInt4(INST_PUSH4, objIndexCopy, (envPtr)); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
@@ -1467,10 +1429,30 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
|
||||
* int threshold);
|
||||
*/
|
||||
|
||||
#define TclFixupForwardJumpToHere(envPtr, fixupPtr, threshold) \
|
||||
TclFixupForwardJump((envPtr), (fixupPtr), \
|
||||
(envPtr)->codeNext-(envPtr)->codeStart-(fixupPtr)->codeOffset, \
|
||||
(threshold))
|
||||
#define TclEmitForwardJump(envPtr, type, pcPtr) \
|
||||
*(pcPtr) = (envPtr)->codeNext - (envPtr)->codeStart; \
|
||||
TclEmitInstInt4(INST_##type##4, 0, (envPtr))
|
||||
|
||||
#define TclEmitForwardJump1(envPtr, type, pcPtr) \
|
||||
*(pcPtr) = (envPtr)->codeNext - (envPtr)->codeStart; \
|
||||
TclEmitInstInt1(INST_##type##1, 0, (envPtr))
|
||||
|
||||
#define TclFixupForwardJump(envPtr, pc, jumpDist) \
|
||||
TclStoreInt4AtPtr((jumpDist), (envPtr)->codeStart + (pc) + 1)
|
||||
|
||||
#define TclFixupForwardJump1(envPtr, pc, jumpDist) \
|
||||
if (((jumpDist) > 127) && ((jumpDist) < -127)) { \
|
||||
Tcl_Panic("TclFixupForwardJump1: bad jump distance %d", jumpDist); \
|
||||
} \
|
||||
TclStoreInt1AtPtr((jumpDist), (envPtr)->codeStart + (pc) + 1)
|
||||
|
||||
#define TclFixupForwardJumpToHere(envPtr, fixup) \
|
||||
TclFixupForwardJump((envPtr), (fixup), \
|
||||
(envPtr)->codeNext-(envPtr)->codeStart-(fixup))
|
||||
|
||||
#define TclFixupForwardJumpToHere1(envPtr, fixup) \
|
||||
TclFixupForwardJump1((envPtr), (fixup), \
|
||||
(envPtr)->codeNext-(envPtr)->codeStart-(fixup))
|
||||
|
||||
/*
|
||||
* Macros to get a signed integer (GET_INT{1,2}) or an unsigned int
|
||||
|
||||
+20
-24
@@ -2085,6 +2085,14 @@ TclNRExecuteByteCode(
|
||||
* Push the callback for bytecode execution
|
||||
*/
|
||||
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
if (tclTraceExec >= 2) {
|
||||
PrintByteCodeInfo(codePtr);
|
||||
fprintf(stdout, " Starting stack top=0\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
TclNRAddCallback(interp, TEBCresume, TD, /* pc */ NULL,
|
||||
/* cleanup */ INT2PTR(0), NULL);
|
||||
return TCL_OK;
|
||||
@@ -2185,14 +2193,6 @@ TEBCresume(
|
||||
|
||||
TEBC_DATA_DIG();
|
||||
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
if (!pc && (tclTraceExec >= 2)) {
|
||||
PrintByteCodeInfo(codePtr);
|
||||
fprintf(stdout, " Starting stack top=%d\n", (int) CURR_DEPTH);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!pc) {
|
||||
/* bytecode is starting from scratch */
|
||||
checkInterp = 0;
|
||||
@@ -2623,25 +2623,21 @@ TEBCresume(
|
||||
}
|
||||
|
||||
case INST_DONE:
|
||||
if (tosPtr > initTosPtr) {
|
||||
/*
|
||||
* Set the interpreter's object result to point to the topmost
|
||||
* object from the stack, and check for a possible [catch]. The
|
||||
* stackTop's level and refCount will be handled by "processCatch"
|
||||
* or "abnormalReturn".
|
||||
*/
|
||||
/*
|
||||
* Set the interpreter's object result to point to the topmost
|
||||
* object from the stack. The stackTop's level and refCount will be
|
||||
* handled by "abnormalReturn".
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, OBJ_AT_TOS);
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
TRACE_WITH_OBJ(("=> return code=%d, result=", result),
|
||||
iPtr->objResultPtr);
|
||||
if (traceInstructions) {
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
#endif
|
||||
goto checkForCatch;
|
||||
TRACE_WITH_OBJ(("=> return code=%d, result=", result),
|
||||
OBJ_AT_TOS);
|
||||
if (traceInstructions) {
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
(void) POP_OBJECT();
|
||||
#endif
|
||||
assert (catchTop == initCatchTop); /* no catch */
|
||||
Tcl_SetObjResult(interp, OBJ_AT_TOS);
|
||||
goto abnormalReturn;
|
||||
|
||||
case INST_PUSH4:
|
||||
|
||||
+1005
-382
File diff suppressed because it is too large
Load Diff
Executable → Regular
Executable → Regular
Reference in New Issue
Block a user