Remove BytecodeEmitter.emitLevel and EmitLevelManager
Categories
(Core :: JavaScript Engine, enhancement, P2)
Tracking
()
Tracking | Status | |
---|---|---|
firefox67 | --- | fixed |
People
(Reporter: arai, Assigned: arai)
References
Details
Attachments
(1 file, 1 obsolete file)
6.21 KB,
patch
|
Waldo
:
review+
|
Details | Diff | Splinter Review |
Looks like it's just to perform updateSourceCoordNotes at the end of top-level script or function script.
we should do that in the caller, BytecodeEmitter::emitFunctionScript and BytecodeEmitter::emitScript.
This will simplify bug 1473796 patch.
Assignee | ||
Comment 1•7 years ago
|
||
Remove BytecodeEmitter.emitLevel
and EmitLevelManager
, for the following reasons:
BytecodeEmitter.emitLevel
and EmitLevelManager
are used only in the following code
that is, whether to call updateSourceCoordNotes
or not on certain case.
bool BytecodeEmitter::emitTree(
ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::WantValue */,
EmitLineNumberNote emitLineNote /* = EMIT_LINENOTE */) {
...
EmitLevelManager elm(this);
...
/* bce->emitLevel == 1 means we're last on the stack, so finish up. */
if (emitLevel == 1) {
if (!updateSourceCoordNotes(pn->pn_pos.end)) {
return false;
}
}
return true;
}
then, emitLevel == 1
condition becomes true only the following 3 callsites (emitTree
is called inside emitLexicalScopeBody
),
and updateSourceCoordNotes
is already called for the same position.
bool BytecodeEmitter::emitScript(ParseNode* body) {
...
if (sc->isEvalContext() && !sc->strict() && body->is<LexicalScopeNode>() &&
!body->as<LexicalScopeNode>().isEmptyScope()) {
...
if (!emitLexicalScopeBody(scope->scopeBody())) { <--- HERE
return false;
}
...
} else {
if (!emitTree(body)) { <--- HERE
return false;
}
}
if (!updateSourceCoordNotes(body->pn_pos.end)) { <-- HERE
return false;
}
and
bool BytecodeEmitter::emitFunctionScript(CodeNode* funNode,
TopLevelFunction isTopLevel) {
...
if (!emitTree(body)) { <--- HERE
return false;
}
if (!updateSourceCoordNotes(body->pn_pos.end)) { <-- HERE
return false;
}
and calling updateSourceCoordNotes
with same position twice has no effect.
Comment 2•7 years ago
|
||
Assignee | ||
Comment 3•7 years ago
|
||
About emitHoistedFunctionsInList
, we're indeed creating SRC_SETLINE
s for function nodes,
but those functions are hoisted and emitted inside the prologue section, that is not the target of source notes.
that results in setting those source notes to the first opcode in the main section.
I'll check some other cases to see whether those source notes are effectful or not.
If they're not, we can drop them.
Here's the example:
code
eval(`
let a;
function x() {
return 20;
}
dis();
`);
output
loc op
----- --
00000: uninitialized # UNINITIALIZED
00001: initlexical 0 # UNINITIALIZED
00005: pop #
00006: lambda function x() {
return 20;
} # FUN
00011: deffun #
main:
00012: undefined # undefined
00013: initlexical 0 # undefined
00017: pop #
00018: getgname "dis" # dis
00023: gimplicitthis "dis" # dis THIS
00028: call 0 # dis(...)
00031: setrval #
00032: debugleavelexicalenv #
00033: retrval #
with calling updateSourceCoordNotes
in emitHoistedFunctionsInList
Source notes:
ofs line pc delta desc args
---- ---- ----- ------ -------- ------
0: 1 12 [ 12] xdelta
1: 1 12 [ 0] setline lineno 5
3: 5 12 [ 0] colspan 1
5: 5 12 [ 0] setline lineno 1
7: 1 12 [ 0] newline
8: 2 12 [ 0] colspan 4
10: 2 18 [ 6] setline lineno 6
12: 6 32 [ 14] xdelta
13: 6 32 [ 0] newline
Scope notes:
index parent start end
1 (none) 0 33
without calling updateSourceCoordNotes
in emitHoistedFunctionsInList
Source notes:
ofs line pc delta desc args
---- ---- ----- ------ -------- ------
0: 1 12 [ 12] xdelta
1: 1 12 [ 0] newline
2: 2 12 [ 0] colspan 4
4: 2 18 [ 6] setline lineno 6
6: 6 32 [ 14] xdelta
7: 6 32 [ 0] newline
Scope notes:
index parent start end
1 (none) 0 33
Assignee | ||
Comment 4•7 years ago
|
||
so far, I don't find any case that the existence of SRC_SETLINE
for hoisted function affects debugger or coverage or anything.
SRC_SETLINE
are used in the following functions.
[js::BytecodeRangeWithPosition::updatePosition
]
Accumulates SRC_COLSPAN
/SRC_SETLINE
/SRC_NEWLINE
up to given PC.
This means source notes in prologue are simply overwritten by source note
for the first opcode in the main section
[js::coverage::LCovSource::writeScript
]
called by js::coverage::LCovRealm::collectCodeCoverageInfo
, which does the almost same as above
[js::PCToLineNumber
]
almost same as above
[js::LineNumberToPC
]
almost same as above
[js::GetScriptLineExtent
]
updateLineNumberNotes
inside emitScript
sets the largest line number,
and others don't affect.
Comment 5•7 years ago
|
||
I was thinking maybe the absence of the source notes would affect line/column information on the error for if a hoisted function would conflict with an immutable binding of the same name in the enclosing environment. Something like
[jwalden@find-waldo-now after]$ cat /tmp/test.js
const x = 3;
eval("let y = 4; function x() { return 2; }");
[jwalden@find-waldo-now after]$ dbg/js/src/js /tmp/test.js
/tmp/test.js:1:20 SyntaxError: redeclaration of const x:
/tmp/test.js:1:20 let y = 4; function x() { return 2; }
/tmp/test.js:1:20 ....................^
Stack:
@/tmp/test.js:2:1
where some of those numbers would change as a consequence. I rather doubt the absence of these notes truly affects nothing, but that's mostly instinct.
Assignee | ||
Comment 6•7 years ago
|
||
redeclaration error happens inside parser, and we don't use source notes there.
I'll check some more cases, and post updated patch if nothing found.
Assignee | ||
Updated•7 years ago
|
Updated•7 years ago
|
Assignee | ||
Comment 7•7 years ago
|
||
Bug 1284719 removed the source note in prologue,
and now we don't have to worry about the source note for hoisted functions.
Updated•7 years ago
|
Assignee | ||
Comment 8•7 years ago
|
||
Comment 9•7 years ago
|
||
bugherder |
Updated•7 years ago
|
Description
•