Fix a couple of jsemit.h glitches, and a benign but confusing hard case to do with extended switch jumps in jsemit.c's OptimizeSpanDeps (158382, r=khanson, sr=shaver).

git-svn-id: svn://10.0.0.236/trunk@126709 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
brendan%mozilla.org
2002-08-08 00:30:20 +00:00
parent 8f3ec4dd13
commit 90087e2107
2 changed files with 34 additions and 8 deletions

View File

@@ -775,6 +775,8 @@ OptimizeSpanDeps(JSContext *cx, JSCodeGenerator *cg)
if (!JOF_TYPE_IS_EXTENDED_JUMP(type)) {
span = SD_TARGET_OFFSET(sd) - pivot;
if (span < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < span) {
ptrdiff_t deltaFromTop = 0;
done = JS_FALSE;
switch (op) {
@@ -793,8 +795,28 @@ OptimizeSpanDeps(JSContext *cx, JSCodeGenerator *cg)
*pc = (jsbytecode) op;
for (sd2 = sdtop; sd2 < sdlimit && sd2->top == top; sd2++) {
if (sd2 > sd)
if (sd2 <= sd) {
/*
* sd2->offset already includes delta as it stood
* before we entered this loop, but it must also
* include the delta relative to top due to all the
* extended jump offset immediates for the opcode
* starting at top, which we extend in this loop.
*
* If there is only one extended jump offset, then
* sd2->offset won't change and this for loop will
* iterate once only.
*/
sd2->offset += deltaFromTop;
deltaFromTop += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN;
} else {
/*
* sd2 comes after sd, and won't be revisited by
* the outer for loop, so we have to increase its
* offset by delta, not merely by deltaFromTop.
*/
sd2->offset += delta;
}
delta += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN;
UpdateJumpTargets(cg->jumpTargets, sd2->offset,

View File

@@ -47,6 +47,10 @@
JS_BEGIN_EXTERN_C
/*
* NB: If you add non-loop STMT_* enumerators, do so before STMT_DO_LOOP or
* you will break the STMT_IS_LOOP macro, just below this enum.
*/
typedef enum JSStmtType {
STMT_BLOCK = 0, /* compound statement: { s1[;... sN] } */
STMT_LABEL = 1, /* labeled statement: L: s */
@@ -57,11 +61,11 @@ typedef enum JSStmtType {
STMT_TRY = 6, /* try statement */
STMT_CATCH = 7, /* catch block */
STMT_FINALLY = 8, /* finally statement */
STMT_DO_LOOP = 9, /* do/while loop statement */
STMT_FOR_LOOP = 10, /* for loop statement */
STMT_FOR_IN_LOOP = 11, /* for/in loop statement */
STMT_WHILE_LOOP = 12, /* while loop statement */
STMT_SUBROUTINE = 13 /* gosub-target subroutine body */
STMT_SUBROUTINE = 9, /* gosub-target subroutine body */
STMT_DO_LOOP = 10, /* do/while loop statement */
STMT_FOR_LOOP = 11, /* for loop statement */
STMT_FOR_IN_LOOP = 12, /* for/in loop statement */
STMT_WHILE_LOOP = 13 /* while loop statement */
} JSStmtType;
#define STMT_IS_LOOP(stmt) ((stmt)->type >= STMT_DO_LOOP)
@@ -154,11 +158,11 @@ struct JSJumpTarget {
#define BITS_PER_PTRDIFF (sizeof(ptrdiff_t) * JS_BITS_PER_BYTE)
#define BITS_PER_BPDELTA (BITS_PER_PTRDIFF - 1 - JT_UNTAG_SHIFT)
#define BPDELTA_MAX ((ptrdiff_t)(JS_BIT(BITS_PER_BPDELTA) - 1))
#define BPDELTA_TO_TN(bp) ((JSJumpTarget *)((bp) << JT_UNTAG_SHIFT))
#define BPDELTA_TO_JT(bp) ((JSJumpTarget *)((bp) << JT_UNTAG_SHIFT))
#define JT_TO_BPDELTA(jt) ((ptrdiff_t)((jsword)(jt) >> JT_UNTAG_SHIFT))
#define SD_SET_TARGET(sd,jt) ((sd)->target = JT_SET_TAG(jt))
#define SD_SET_BPDELTA(sd,bp) ((sd)->target = BPDELTA_TO_TN(bp))
#define SD_SET_BPDELTA(sd,bp) ((sd)->target = BPDELTA_TO_JT(bp))
#define SD_GET_BPDELTA(sd) (JS_ASSERT(!JT_HAS_TAG((sd)->target)), \
JT_TO_BPDELTA((sd)->target))
#define SD_TARGET_OFFSET(sd) (JS_ASSERT(JT_HAS_TAG((sd)->target)), \