diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 4833bd3ca945..18de600fe4d4 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -7846,22 +7846,25 @@ bool BytecodeEmitter::emitOptionalDotExpression(PropertyAccessBase* prop, bool isSuper, OptionalEmitter& oe) { if (!poe.prepareForObj()) { + // [stack] return false; } + if (isSuper) { UnaryNode* base = &prop->expression().as(); if (!emitGetThisForSuperBase(base)) { - // [stack] THIS + // [stack] OBJ return false; } } else { if (!emitOptionalTree(&prop->expression(), oe)) { - // [stack] OBJ + // [stack] OBJ return false; } } if (prop->isKind(ParseNodeKind::OptionalDotExpr)) { + MOZ_ASSERT(!isSuper); if (!oe.emitJumpShortCircuit()) { // [stack] # if Jump // [stack] UNDEFINED-OR-NULL @@ -7872,7 +7875,7 @@ bool BytecodeEmitter::emitOptionalDotExpression(PropertyAccessBase* prop, } if (!poe.emitGet(prop->key().atom())) { - // [stack] PROP + // [stack] PROP return false; } @@ -7883,38 +7886,26 @@ bool BytecodeEmitter::emitOptionalElemExpression(PropertyByValueBase* elem, ElemOpEmitter& eoe, bool isSuper, OptionalEmitter& oe) { - if (isSuper) { - if (!eoe.prepareForObj()) { - // [stack] - return false; - } - UnaryNode* base = &elem->expression().as(); - if (!emitGetThisForSuperBase(base)) { - // [stack] THIS - return false; - } - if (!eoe.prepareForKey()) { - // [stack] THIS - return false; - } - if (!emitTree(&elem->key())) { - // [stack] THIS KEY - return false; - } - - return true; - } - if (!eoe.prepareForObj()) { // [stack] return false; } - if (!emitOptionalTree(&elem->expression(), oe)) { - // [stack] OBJ - return false; + + if (isSuper) { + UnaryNode* base = &elem->expression().as(); + if (!emitGetThisForSuperBase(base)) { + // [stack] OBJ + return false; + } + } else { + if (!emitOptionalTree(&elem->expression(), oe)) { + // [stack] OBJ + return false; + } } if (elem->isKind(ParseNodeKind::OptionalElemExpr)) { + MOZ_ASSERT(!isSuper); if (!oe.emitJumpShortCircuit()) { // [stack] # if Jump // [stack] UNDEFINED-OR-NULL @@ -7938,6 +7929,7 @@ bool BytecodeEmitter::emitOptionalElemExpression(PropertyByValueBase* elem, // [stack] ELEM return false; } + return true; } diff --git a/js/src/tests/non262/expressions/optional-chain-super-elem.js b/js/src/tests/non262/expressions/optional-chain-super-elem.js new file mode 100644 index 000000000000..3b912a9adad4 --- /dev/null +++ b/js/src/tests/non262/expressions/optional-chain-super-elem.js @@ -0,0 +1,12 @@ +// Don't assert. + +var obj = { + m() { + super[0]?.a + } +}; + +obj.m(); + +if (typeof reportCompare === "function") + reportCompare(true, true);