diff --git a/js/src/frontend/ElemOpEmitter.cpp b/js/src/frontend/ElemOpEmitter.cpp index 8f901d1b3d939..553022ad6757e 100644 --- a/js/src/frontend/ElemOpEmitter.cpp +++ b/js/src/frontend/ElemOpEmitter.cpp @@ -48,31 +48,38 @@ bool ElemOpEmitter::prepareForKey() { bool ElemOpEmitter::emitGet() { MOZ_ASSERT(state_ == State::Key); - // Inc/dec and compound assignment use the KEY twice, but if it's an object, - // it must be converted ToPropertyKey only once, per spec. - if (isIncDec() || isCompoundAssignment()) { - if (!bce_->emit1(JSOp::ToPropertyKey)) { - // [stack] # if Super - // [stack] THIS KEY - // [stack] # otherwise - // [stack] OBJ KEY - return false; - } - } - if (isSuper()) { if (!bce_->emitSuperBase()) { // [stack] THIS? THIS KEY SUPERBASE return false; } } + + // Inc/dec and compound assignment use the KEY twice, but if it's an object, + // it must be converted by ToPropertyKey only once, per spec. if (isIncDec() || isCompoundAssignment()) { if (isSuper()) { + if (!bce_->emit1(JSOp::Swap)) { + // [stack] THIS SUPERBASE KEY + return false; + } + if (!bce_->emit1(JSOp::ToPropertyKey)) { + // [stack] THIS SUPERBASE KEY + return false; + } + if (!bce_->emit1(JSOp::Swap)) { + // [stack] THIS KEY SUPERBASE + return false; + } if (!bce_->emitDupAt(2, 3)) { // [stack] THIS KEY SUPERBASE THIS KEY SUPERBASE return false; } } else { + if (!bce_->emit1(JSOp::ToPropertyKey)) { + // [stack] OBJ KEY + return false; + } if (!bce_->emit1(JSOp::Dup2)) { // [stack] OBJ KEY OBJ KEY return false;