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:
@@ -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,
|
||||
|
||||
@@ -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)), \
|
||||
|
||||
Reference in New Issue
Block a user