Bug 885514: Don't emit top-level GetRval/SetRval in TryEmitter r=arai

Differential Revision: https://phabricator.services.mozilla.com/D142117
This commit is contained in:
Iain Ireland 2022-03-30 23:19:47 +00:00
parent fa9ee479c1
commit 7869d6e53f
3 changed files with 21 additions and 7 deletions

View File

@ -783,10 +783,15 @@ bool NonLocalExitControl::prepareForNonLocalJump(NestableControl* target) {
TryFinallyControl& finallyControl = control->as<TryFinallyControl>();
if (finallyControl.emittingSubroutine()) {
/*
* There's a [resume-index-or-exception, throwing] pair and the
* possible return value on the stack that we need to pop.
* There's a [resume-index-or-exception, throwing] pair on
* the stack that we need to pop. If the script is not a
* noScriptRval script, we also need to pop the cached rval.
*/
npops += 3;
if (bce_->sc->noScriptRval()) {
npops += 2;
} else {
npops += 3;
}
} else {
if (!flushPops(bce_)) {
return false;

View File

@ -120,7 +120,7 @@ bool TryEmitter::emitCatch() {
MOZ_ASSERT(bce_->bytecodeSection().stackDepth() == depth_);
if (controlKind_ == ControlKind::Syntactic) {
if (shouldUpdateRval()) {
// Clear the frame's return value that might have been set by the
// try block:
//
@ -216,7 +216,7 @@ bool TryEmitter::emitFinally(
return false;
}
if (controlKind_ == ControlKind::Syntactic) {
if (shouldUpdateRval()) {
if (!bce_->emit1(JSOp::GetRval)) {
return false;
}
@ -242,7 +242,7 @@ bool TryEmitter::emitFinally(
bool TryEmitter::emitFinallyEnd() {
MOZ_ASSERT(state_ == State::Finally);
if (controlKind_ == ControlKind::Syntactic) {
if (shouldUpdateRval()) {
if (!bce_->emit1(JSOp::SetRval)) {
return false;
}
@ -345,3 +345,7 @@ bool TryEmitter::emitEnd() {
#endif
return true;
}
bool TryEmitter::shouldUpdateRval() const {
return controlKind_ == ControlKind::Syntactic && !bce_->sc->noScriptRval();
}

View File

@ -69,7 +69,8 @@ class MOZ_STACK_CLASS TryEmitter {
// return value. For syntactic try-catch-finally, the bytecode marked with
// "*" are emitted to clear return value with `undefined` before the catch
// block and the finally block, and also to save/restore the return value
// before/after the finally block.
// before/after the finally block. Note that these instructions are not
// emitted for noScriptRval scripts that don't track the return value.
//
// JSOp::Try offsetOf(jumpToEnd)
//
@ -190,6 +191,10 @@ class MOZ_STACK_CLASS TryEmitter {
return tryOpOffset_ + BytecodeOffsetDiff(JSOpLength_Try);
}
// Returns true if catch and finally blocks should handle the frame's
// return value.
bool shouldUpdateRval() const;
// Jump to the finally block. After the finally block executes,
// fall through to the code following the finally block.
[[nodiscard]] bool emitJumpToFinallyWithFallthrough();