mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 927782 - Part 3: Add DEBUGLEAVEBLOCK opcode to invalidate live DebugScopes. r=luke
This commit is contained in:
parent
ab257efdd2
commit
7d7f78b80c
@ -588,6 +588,8 @@ EmitNonLocalJumpFixup(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *t
|
||||
stmt = stmt->down;
|
||||
if (stmt == toStmt)
|
||||
break;
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_LEAVEFORLETIN) < 0)
|
||||
return false;
|
||||
if (stmt->type == STMT_FOR_OF_LOOP) {
|
||||
@ -600,6 +602,8 @@ EmitNonLocalJumpFixup(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *t
|
||||
EMIT_UINT16_IMM_OP(JSOP_POPN, popCount);
|
||||
} else {
|
||||
/* There is a Block object with locals on the stack to pop. */
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, blockObjCount);
|
||||
}
|
||||
}
|
||||
@ -2622,8 +2626,11 @@ EmitSwitch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (!PopStatementBCE(cx, bce))
|
||||
return false;
|
||||
|
||||
if (pn->pn_right->isKind(PNK_LEXICALSCOPE))
|
||||
if (pn->pn_right->isKind(PNK_LEXICALSCOPE)) {
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, blockObjCount);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3941,6 +3948,8 @@ EmitTry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
*/
|
||||
if (Emit1(cx, bce, JSOP_THROWING) < 0)
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, count);
|
||||
JS_ASSERT(bce->stackDepth == depth);
|
||||
}
|
||||
@ -4200,6 +4209,8 @@ EmitLet(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pnLet)
|
||||
if (!EmitTree(cx, bce, letBody->pn_expr))
|
||||
return false;
|
||||
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
JSOp leaveOp = letBody->getOp();
|
||||
JS_ASSERT(leaveOp == JSOP_LEAVEBLOCK || leaveOp == JSOP_LEAVEBLOCKEXPR);
|
||||
EMIT_UINT16_IMM_OP(leaveOp, blockObj->slotCount());
|
||||
@ -4233,6 +4244,8 @@ EmitLexicalScope(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (!EmitTree(cx, bce, pn->pn_expr))
|
||||
return false;
|
||||
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, slots);
|
||||
|
||||
return PopStatementBCE(cx, bce);
|
||||
@ -4410,6 +4423,8 @@ EmitForOf(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
|
||||
if (letDecl) {
|
||||
if (!PopStatementBCE(cx, bce))
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_LEAVEFORLETIN) < 0)
|
||||
return false;
|
||||
}
|
||||
@ -4569,6 +4584,8 @@ EmitForIn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
|
||||
if (letDecl) {
|
||||
if (!PopStatementBCE(cx, bce))
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_LEAVEFORLETIN) < 0)
|
||||
return false;
|
||||
}
|
||||
|
@ -2625,6 +2625,21 @@ BaselineCompiler::emit_JSOP_ENTERLET2()
|
||||
return emitEnterBlock();
|
||||
}
|
||||
|
||||
typedef bool (*DebugLeaveBlockFn)(JSContext *, BaselineFrame *);
|
||||
static const VMFunction DebugLeaveBlockInfo = FunctionInfo<DebugLeaveBlockFn>(jit::DebugLeaveBlock);
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_DEBUGLEAVEBLOCK()
|
||||
{
|
||||
// Call a stub to pop the block from the block chain.
|
||||
prepareVMCall();
|
||||
|
||||
masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
|
||||
pushArg(R0.scratchReg());
|
||||
|
||||
return callVM(DebugLeaveBlockInfo);
|
||||
}
|
||||
|
||||
typedef bool (*LeaveBlockFn)(JSContext *, BaselineFrame *);
|
||||
static const VMFunction LeaveBlockInfo = FunctionInfo<LeaveBlockFn>(jit::LeaveBlock);
|
||||
|
||||
|
@ -152,6 +152,7 @@ namespace jit {
|
||||
_(JSOP_LEAVEBLOCK) \
|
||||
_(JSOP_LEAVEBLOCKEXPR) \
|
||||
_(JSOP_LEAVEFORLETIN) \
|
||||
_(JSOP_DEBUGLEAVEBLOCK) \
|
||||
_(JSOP_EXCEPTION) \
|
||||
_(JSOP_DEBUGGER) \
|
||||
_(JSOP_ARGUMENTS) \
|
||||
|
@ -55,9 +55,6 @@ BaselineFrame::popBlock(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(hasBlockChain());
|
||||
|
||||
if (cx->compartment()->debugMode())
|
||||
DebugScopes::onPopBlock(cx, this);
|
||||
|
||||
if (blockChain_->needsClone()) {
|
||||
JS_ASSERT(scopeChain_->as<ClonedBlockObject>().staticBlock() == *blockChain_);
|
||||
popOffScopeChain();
|
||||
|
@ -894,6 +894,17 @@ LeaveBlock(JSContext *cx, BaselineFrame *frame)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DebugLeaveBlock(JSContext *cx, BaselineFrame *frame)
|
||||
{
|
||||
JS_ASSERT(frame->hasBlockChain());
|
||||
|
||||
if (JS_UNLIKELY(cx->compartment()->debugMode()))
|
||||
DebugScopes::onPopBlock(cx, frame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
InitBaselineFrameForOsr(BaselineFrame *frame, StackFrame *interpFrame, uint32_t numStackValues)
|
||||
{
|
||||
|
@ -654,6 +654,7 @@ bool OnDebuggerStatement(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bo
|
||||
|
||||
bool EnterBlock(JSContext *cx, BaselineFrame *frame, Handle<StaticBlockObject *> block);
|
||||
bool LeaveBlock(JSContext *cx, BaselineFrame *frame);
|
||||
bool DebugLeaveBlock(JSContext *cx, BaselineFrame *frame);
|
||||
|
||||
bool InitBaselineFrameForOsr(BaselineFrame *frame, StackFrame *interpFrame,
|
||||
uint32_t numStackValues);
|
||||
|
@ -438,9 +438,8 @@ OPDEF(JSOP_TYPEOFEXPR, 197,"typeofexpr", NULL, 1, 1, 1, JOF_BYTE|JOF_DE
|
||||
*/
|
||||
OPDEF(JSOP_ENTERBLOCK, 198,"enterblock", NULL, 5, 0, -1, JOF_OBJECT)
|
||||
OPDEF(JSOP_LEAVEBLOCK, 199,"leaveblock", NULL, 3, -1, 0, JOF_UINT16)
|
||||
OPDEF(JSOP_DEBUGLEAVEBLOCK, 200,"debugleaveblock", NULL, 1, 0, 0, JOF_BYTE)
|
||||
|
||||
|
||||
OPDEF(JSOP_UNUSED200, 200,"unused200", NULL, 1, 0, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_UNUSED201, 201,"unused201", NULL, 1, 0, 0, JOF_BYTE)
|
||||
|
||||
/*
|
||||
|
@ -855,6 +855,8 @@ js::UnwindScope(JSContext *cx, AbstractFramePtr frame, uint32_t stackDepth)
|
||||
case ScopeIter::Block:
|
||||
if (si.staticBlock().stackDepth() < stackDepth)
|
||||
return;
|
||||
if (cx->compartment()->debugMode())
|
||||
DebugScopes::onPopBlock(cx, frame);
|
||||
frame.popBlock(cx);
|
||||
break;
|
||||
case ScopeIter::With:
|
||||
@ -1533,7 +1535,6 @@ CASE(JSOP_UNUSED191)
|
||||
CASE(JSOP_UNUSED192)
|
||||
CASE(JSOP_UNUSED194)
|
||||
CASE(JSOP_UNUSED196)
|
||||
CASE(JSOP_UNUSED200)
|
||||
CASE(JSOP_UNUSED201)
|
||||
CASE(JSOP_GETFUNNS)
|
||||
CASE(JSOP_UNUSED208)
|
||||
@ -3268,6 +3269,18 @@ CASE(JSOP_LEAVEBLOCKEXPR)
|
||||
}
|
||||
END_CASE(JSOP_LEAVEBLOCK)
|
||||
|
||||
CASE(JSOP_DEBUGLEAVEBLOCK)
|
||||
{
|
||||
JS_ASSERT(REGS.fp()->hasBlockChain());
|
||||
|
||||
// FIXME: This opcode should not be necessary. The debugger shouldn't need
|
||||
// help from bytecode to do its job. See bug 927782.
|
||||
|
||||
if (JS_UNLIKELY(cx->compartment()->debugMode()))
|
||||
DebugScopes::onPopBlock(cx, REGS.fp());
|
||||
}
|
||||
END_CASE(JSOP_DEBUGLEAVEBLOCK)
|
||||
|
||||
CASE(JSOP_GENERATOR)
|
||||
{
|
||||
JS_ASSERT(!cx->isExceptionPending());
|
||||
|
@ -372,11 +372,6 @@ StackFrame::pushBlock(JSContext *cx, StaticBlockObject &block)
|
||||
void
|
||||
StackFrame::popBlock(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(hasBlockChain());
|
||||
|
||||
if (JS_UNLIKELY(cx->compartment()->debugMode()))
|
||||
DebugScopes::onPopBlock(cx, this);
|
||||
|
||||
if (blockChain_->needsClone()) {
|
||||
JS_ASSERT(scopeChain_->as<ClonedBlockObject>().staticBlock() == *blockChain_);
|
||||
popOffScopeChain();
|
||||
|
Loading…
Reference in New Issue
Block a user