зеркало из https://github.com/mozilla/gecko-dev.git
Bug 601398 - Use new instructions, rather than source notes, to obtain block chain (r=igor)
This commit is contained in:
Родитель
5fcaf2d864
Коммит
bf34ff421b
|
@ -1514,15 +1514,20 @@ EmitNonLocalJumpFixup(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
EmitBlockChain(JSContext *cx, JSCodeGenerator *cg)
|
||||
EmitKnownBlockChain(JSContext *cx, JSCodeGenerator *cg, JSObjectBox *box)
|
||||
{
|
||||
JSObjectBox *box = cg->blockChainBox;
|
||||
if (box)
|
||||
return EmitIndexOp(cx, JSOP_BLOCKCHAIN, box->index, cg);
|
||||
else
|
||||
return js_Emit1(cx, cg, JSOP_NULLBLOCKCHAIN) >= 0;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
EmitBlockChain(JSContext *cx, JSCodeGenerator *cg)
|
||||
{
|
||||
return EmitKnownBlockChain(cx, cg, cg->blockChainBox);
|
||||
}
|
||||
|
||||
static ptrdiff_t
|
||||
EmitGoto(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt,
|
||||
ptrdiff_t *lastp, JSAtomListElement *label, JSSrcNoteType noteType)
|
||||
|
@ -1541,7 +1546,14 @@ EmitGoto(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt,
|
|||
if (index < 0)
|
||||
return -1;
|
||||
|
||||
return EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, lastp);
|
||||
ptrdiff_t result = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, lastp);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
if (!EmitBlockChain(cx, cg))
|
||||
return -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -5368,16 +5380,17 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
|
||||
tryEnd = CG_OFFSET(cg);
|
||||
|
||||
JSObjectBox *prevBox = NULL;
|
||||
/* If this try has a catch block, emit it. */
|
||||
pn2 = pn->pn_kid2;
|
||||
lastCatch = NULL;
|
||||
if (pn2) {
|
||||
JSObjectBox *prevBox = NULL;
|
||||
uintN count = 0; /* previous catch block's population */
|
||||
|
||||
/*
|
||||
* The emitted code for a catch block looks like:
|
||||
*
|
||||
* blockchain
|
||||
* [throwing] only if 2nd+ catch block
|
||||
* [leaveblock] only if 2nd+ catch block
|
||||
* enterblock with SRC_CATCH
|
||||
|
@ -5403,6 +5416,9 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
JS_ASSERT(cg->stackDepth == depth);
|
||||
guardJump = GUARDJUMP(stmtInfo);
|
||||
if (guardJump != -1) {
|
||||
if (EmitKnownBlockChain(cx, cg, prevBox) < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Fix up and clean up previous catch block. */
|
||||
CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, guardJump);
|
||||
|
||||
|
@ -5487,6 +5503,9 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
* stack unbalanced.
|
||||
*/
|
||||
if (lastCatch && lastCatch->pn_kid2) {
|
||||
if (EmitKnownBlockChain(cx, cg, prevBox) < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, GUARDJUMP(stmtInfo));
|
||||
|
||||
/* Sync the stack to take into account pushed exception. */
|
||||
|
@ -5501,6 +5520,9 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
js_Emit1(cx, cg, JSOP_THROW) < 0) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (EmitBlockChain(cx, cg) < 0)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JS_ASSERT(cg->stackDepth == depth);
|
||||
|
@ -5682,6 +5704,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
CG_BASE(cg)[top] = JSOP_SETRVAL;
|
||||
if (js_Emit1(cx, cg, JSOP_RETRVAL) < 0)
|
||||
return JS_FALSE;
|
||||
if (EmitBlockChain(cx, cg) < 0)
|
||||
return JS_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -181,28 +181,29 @@ js_GetBlockChain(JSContext *cx, JSStackFrame *fp)
|
|||
jsbytecode *pc = fp->hasImacropc() ? fp->imacropc() : fp->pc(cx);
|
||||
|
||||
JS_ASSERT(pc >= start && pc < script->code + script->length);
|
||||
|
||||
ptrdiff_t oplen;
|
||||
JSObject *blockChain = NULL;
|
||||
for (jsbytecode *p = start; p < pc; p += oplen) {
|
||||
JSOp op = js_GetOpcode(cx, script, p);
|
||||
const JSCodeSpec *cs = &js_CodeSpec[op];
|
||||
oplen = cs->length;
|
||||
if (oplen < 0)
|
||||
oplen = js_GetVariableBytecodeLength(p);
|
||||
|
||||
if (op == JSOP_ENTERBLOCK) {
|
||||
blockChain = script->getObject(GET_INDEX(p));
|
||||
} else if (op == JSOP_LEAVEBLOCK || op == JSOP_LEAVEBLOCKEXPR) {
|
||||
/*
|
||||
* Some LEAVEBLOCK instructions are due to early exits via
|
||||
* return/break/etc. from block-scoped loops and functions.
|
||||
* We should ignore these instructions, since they don't really
|
||||
* signal the end of the block.
|
||||
*/
|
||||
jssrcnote *sn = js_GetSrcNote(script, p);
|
||||
if (!(sn && SN_TYPE(sn) == SRC_HIDDEN))
|
||||
JSObject *blockChain = NULL;
|
||||
if (*pc == JSOP_BLOCKCHAIN) {
|
||||
blockChain = script->getObject(GET_INDEX(pc));
|
||||
} else if (*pc == JSOP_NULLBLOCKCHAIN) {
|
||||
blockChain = NULL;
|
||||
} else {
|
||||
ptrdiff_t oplen;
|
||||
for (jsbytecode *p = start; p < pc; p += oplen) {
|
||||
JSOp op = js_GetOpcode(cx, script, p);
|
||||
const JSCodeSpec *cs = &js_CodeSpec[op];
|
||||
oplen = cs->length;
|
||||
if (oplen < 0)
|
||||
oplen = js_GetVariableBytecodeLength(p);
|
||||
|
||||
if (op == JSOP_ENTERBLOCK)
|
||||
blockChain = script->getObject(GET_INDEX(p));
|
||||
else if (op == JSOP_LEAVEBLOCK || op == JSOP_LEAVEBLOCKEXPR)
|
||||
blockChain = blockChain->getParent();
|
||||
else if (op == JSOP_BLOCKCHAIN)
|
||||
blockChain = script->getObject(GET_INDEX(p));
|
||||
else if (op == JSOP_NULLBLOCKCHAIN)
|
||||
blockChain = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6746,8 +6747,6 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||
|
||||
switch (tn->kind) {
|
||||
case JSTRY_CATCH:
|
||||
JS_ASSERT(js_GetOpcode(cx, regs.fp->script(), regs.pc) == JSOP_ENTERBLOCK);
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
/* Catch cannot intercept the closing of a generator. */
|
||||
if (JS_UNLIKELY(cx->exception.isMagic(JS_GENERATOR_CLOSING)))
|
||||
|
|
|
@ -4,7 +4,7 @@ x = "notset";
|
|||
function myparent(nested) {
|
||||
if (nested) {
|
||||
/* noop call in myparent */
|
||||
trap(myparent, 49, "success()");
|
||||
trap(myparent, 50, "success()");
|
||||
} else {
|
||||
myparent(true);
|
||||
x = "failure";
|
||||
|
|
|
@ -13,7 +13,7 @@ function myparent(nested) {
|
|||
}
|
||||
}
|
||||
/* JSOP_CALL to doNothing in myparent with nested = false. */
|
||||
trap(myparent, 35, "myparent(true)");
|
||||
trap(myparent, 36, "myparent(true)");
|
||||
|
||||
function success() {
|
||||
x = "success";
|
||||
|
|
Загрузка…
Ссылка в новой задаче