mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 1129813 - special-case "while" and "for" line notes; r=jimb
This commit is contained in:
parent
d56c319644
commit
87fd9b0316
@ -5770,14 +5770,17 @@ BytecodeEmitter::emitCStyleFor(ParseNode* pn, ptrdiff_t top)
|
|||||||
bool
|
bool
|
||||||
BytecodeEmitter::emitFor(ParseNode* pn, ptrdiff_t top)
|
BytecodeEmitter::emitFor(ParseNode* pn, ptrdiff_t top)
|
||||||
{
|
{
|
||||||
|
if (pn->pn_left->isKind(PNK_FORHEAD))
|
||||||
|
return emitCStyleFor(pn, top);
|
||||||
|
|
||||||
|
if (!updateLineNumberNotes(pn->pn_pos.begin))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (pn->pn_left->isKind(PNK_FORIN))
|
if (pn->pn_left->isKind(PNK_FORIN))
|
||||||
return emitForIn(pn, top);
|
return emitForIn(pn, top);
|
||||||
|
|
||||||
if (pn->pn_left->isKind(PNK_FOROF))
|
MOZ_ASSERT(pn->pn_left->isKind(PNK_FOROF));
|
||||||
return emitForOf(StmtType::FOR_OF_LOOP, pn, top);
|
return emitForOf(StmtType::FOR_OF_LOOP, pn, top);
|
||||||
|
|
||||||
MOZ_ASSERT(pn->pn_left->isKind(PNK_FORHEAD));
|
|
||||||
return emitCStyleFor(pn, top);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_NEVER_INLINE bool
|
MOZ_NEVER_INLINE bool
|
||||||
@ -6021,6 +6024,20 @@ BytecodeEmitter::emitWhile(ParseNode* pn, ptrdiff_t top)
|
|||||||
* . . .
|
* . . .
|
||||||
* N N*(ifeq-fail; goto); ifeq-pass goto; N*ifne-pass; ifne-fail
|
* N N*(ifeq-fail; goto); ifeq-pass goto; N*ifne-pass; ifne-fail
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// If we have a single-line while, like "while (x) ;", we want to
|
||||||
|
// emit the line note before the initial goto, so that the
|
||||||
|
// debugger sees a single entry point. This way, if there is a
|
||||||
|
// breakpoint on the line, it will only fire once; and "next"ing
|
||||||
|
// will skip the whole loop. However, for the multi-line case we
|
||||||
|
// want to emit the line note after the initial goto, so that
|
||||||
|
// "cont" stops on each iteration -- but without a stop before the
|
||||||
|
// first iteration.
|
||||||
|
if (parser->tokenStream.srcCoords.lineNum(pn->pn_pos.begin) ==
|
||||||
|
parser->tokenStream.srcCoords.lineNum(pn->pn_pos.end) &&
|
||||||
|
!updateSourceCoordNotes(pn->pn_pos.begin))
|
||||||
|
return false;
|
||||||
|
|
||||||
LoopStmtInfo stmtInfo(cx);
|
LoopStmtInfo stmtInfo(cx);
|
||||||
pushLoopStatement(&stmtInfo, StmtType::WHILE_LOOP, top);
|
pushLoopStatement(&stmtInfo, StmtType::WHILE_LOOP, top);
|
||||||
|
|
||||||
@ -7547,8 +7564,11 @@ BytecodeEmitter::emitTree(ParseNode* pn)
|
|||||||
ptrdiff_t top = offset();
|
ptrdiff_t top = offset();
|
||||||
pn->pn_offset = top;
|
pn->pn_offset = top;
|
||||||
|
|
||||||
/* Emit notes to tell the current bytecode's source line number. */
|
/* Emit notes to tell the current bytecode's source line number.
|
||||||
if (!updateLineNumberNotes(pn->pn_pos.begin))
|
However, a couple trees require special treatment; see the
|
||||||
|
relevant emitter functions for details. */
|
||||||
|
if (pn->getKind() != PNK_WHILE && pn->getKind() != PNK_FOR &&
|
||||||
|
!updateLineNumberNotes(pn->pn_pos.begin))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (pn->getKind()) {
|
switch (pn->getKind()) {
|
||||||
|
24
js/src/jit-test/tests/debug/Script-getLineOffsets-08.js
Normal file
24
js/src/jit-test/tests/debug/Script-getLineOffsets-08.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// A "while" or a "for" loop should have a single entry point.
|
||||||
|
|
||||||
|
var g = newGlobal();
|
||||||
|
var dbg = new Debugger(g);
|
||||||
|
|
||||||
|
dbg.onDebuggerStatement = function(frame) {
|
||||||
|
var s = frame.eval('f').return.script;
|
||||||
|
|
||||||
|
// There should be just a single entry point for the first line of
|
||||||
|
// the function. See below to understand the "+2".
|
||||||
|
assertEq(s.getLineOffsets(g.line0 + 2).length, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function test(code) {
|
||||||
|
g.eval('var line0 = Error().lineNumber;\n' +
|
||||||
|
'function f() {\n' + // line0 + 1
|
||||||
|
code + '\n' + // line0 + 2 -- see above
|
||||||
|
'}\n' +
|
||||||
|
'debugger;');
|
||||||
|
}
|
||||||
|
|
||||||
|
test('while (false)\n;');
|
||||||
|
test('for (;false;)\n;');
|
Loading…
Reference in New Issue
Block a user