From 74032644f57e4f672703220764a10c3f1a67fa9e Mon Sep 17 00:00:00 2001 From: Martok Date: Sat, 1 Apr 2023 17:41:30 +0200 Subject: [PATCH] Issue #2155 - Follow-up: Reorder super-property evaluation order per latest spec change Fix regression from difference between Interpreter (old) and ElemOpEmitter (new). We don't have any Ion/IC support for these ops. Based-on: m-c 1472211 --- js/src/frontend/BytecodeEmitter.h | 4 ---- js/src/frontend/ElemOpEmitter.cpp | 4 ++++ js/src/jsopcode.cpp | 2 +- js/src/vm/Interpreter.cpp | 8 ++++---- js/src/vm/Opcodes.h | 10 +++++----- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h index 79c36c5004..d909c33084 100644 --- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -581,7 +581,6 @@ struct MOZ_STACK_CLASS BytecodeEmitter MOZ_MUST_USE bool emitElemObjAndKey(PropertyByValue* elem, bool isSuper, ElemOpEmitter& eoe); MOZ_MUST_USE bool emitElemOpBase(JSOp op); - MOZ_MUST_USE bool emitElemOp(ParseNode* pn, JSOp op); MOZ_MUST_USE bool emitElemIncDec(ParseNode* pn); MOZ_MUST_USE bool emitCatch(ParseNode* pn); @@ -805,9 +804,6 @@ struct MOZ_STACK_CLASS BytecodeEmitter MOZ_MUST_USE bool emitSpread(bool allowSelfHosted = false); MOZ_MUST_USE bool emitClass(ParseNode* pn); - MOZ_MUST_USE bool emitSuperElemOperands(ParseNode* pn, - EmitElemOption opts = EmitElemOption::Get); - MOZ_MUST_USE bool emitSuperElemOp(ParseNode* pn, JSOp op, bool isCall = false); }; class MOZ_RAII AutoCheckUnstableEmitterScope { diff --git a/js/src/frontend/ElemOpEmitter.cpp b/js/src/frontend/ElemOpEmitter.cpp index 916cca08c1..2644072337 100644 --- a/js/src/frontend/ElemOpEmitter.cpp +++ b/js/src/frontend/ElemOpEmitter.cpp @@ -41,6 +41,8 @@ ElemOpEmitter::prepareForKey() } } if (isCall()) { + // We need a second |this| that will be consumed during computation of + // the property value. (The original |this| is passed to the call.) if (!bce_->emit1(JSOP_DUP)) { // [Super] // // THIS THIS // // [Other] @@ -60,6 +62,8 @@ ElemOpEmitter::emitGet() { MOZ_ASSERT(state_ == State::Key); + // We need to convert the key to an object id first, so that we do not do + // it inside both the GETELEM and the SETELEM. if (isIncDec() || isCompoundAssignment()) { if (!bce_->emit1(JSOP_TOID)) { // [Super] // // THIS KEY diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 1ba19731eb..5573d3d48b 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -1330,7 +1330,7 @@ ExpressionDecompiler::decompilePC(jsbytecode* pc) write("]"); case JSOP_GETELEM_SUPER: return write("super[") && - decompilePCForStackOperand(pc, -3) && + decompilePCForStackOperand(pc, -2) && write("]"); case JSOP_NULL: return write(js_null_str); diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index b95e533b6e..3951af675e 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -2853,9 +2853,9 @@ END_CASE(JSOP_GETELEM) CASE(JSOP_GETELEM_SUPER) { - HandleValue rval = REGS.stackHandleAt(-3); ReservedRooted receiver(&rootObject0); - FETCH_OBJECT(cx, -2, receiver); + FETCH_OBJECT(cx, -3, receiver); + HandleValue rval = REGS.stackHandleAt(-2); ReservedRooted obj(&rootObject1, ®S.sp[-1].toObject()); MutableHandleValue res = REGS.stackHandleAt(-3); @@ -2897,9 +2897,9 @@ CASE(JSOP_STRICTSETELEM_SUPER) static_assert(JSOP_SETELEM_SUPER_LENGTH == JSOP_STRICTSETELEM_SUPER_LENGTH, "setelem-super and strictsetelem-super must be the same size"); + ReservedRooted receiver(&rootValue0, REGS.sp[-4]); ReservedRooted id(&rootId0); - FETCH_ELEMENT_ID(-4, id); - ReservedRooted receiver(&rootValue0, REGS.sp[-3]); + FETCH_ELEMENT_ID(-3, id); ReservedRooted obj(&rootObject1, ®S.sp[-2].toObject()); HandleValue value = REGS.stackHandleAt(-1); diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h index 8328dfc994..ba1c820218 100644 --- a/js/src/vm/Opcodes.h +++ b/js/src/vm/Opcodes.h @@ -535,7 +535,7 @@ macro(JSOP_GETELEM, 55, "getelem", NULL, 1, 2, 1, JOF_BYTE |JOF_ELEM|JOF_TYPESET|JOF_LEFTASSOC) \ /* * Pops the top three values on the stack as 'val', 'propval' and 'obj', - * sets 'propval' property of 'obj' as 'val', pushes 'obj' onto the + * sets 'propval' property of 'obj' as 'val', pushes 'val' onto the * stack. * Category: Literals * Type: Object @@ -545,7 +545,7 @@ macro(JSOP_SETELEM, 56, "setelem", NULL, 1, 3, 1, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_DETECTING|JOF_CHECKSLOPPY) \ /* * Pops the top three values on the stack as 'val', 'propval' and 'obj', - * sets 'propval' property of 'obj' as 'val', pushes 'obj' onto the + * sets 'propval' property of 'obj' as 'val', pushes 'val' onto the * stack. Throws a TypeError if the set fails, per strict mode * semantics. * Category: Literals @@ -1277,7 +1277,7 @@ * Category: Literals * Type: Object * Operands: - * Stack: receiver, obj, propval => obj[propval] + * Stack: receiver, propval, obj => obj[propval] */ \ macro(JSOP_GETELEM_SUPER, 125, "getelem-super", NULL, 1, 3, 1, JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC) \ /* @@ -1637,7 +1637,7 @@ * Category: Literals * Type: Object * Operands: - * Stack: propval, receiver, obj, val => val + * Stack: receiver, propval, obj, val => val */ \ macro(JSOP_SETELEM_SUPER, 158, "setelem-super", NULL, 1, 4, 1, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_DETECTING|JOF_CHECKSLOPPY) \ /* @@ -1646,7 +1646,7 @@ * Category: Literals * Type: Object * Operands: - * Stack: propval, receiver, obj, val => val + * Stack: receiver, propval, obj, val => val */ \ macro(JSOP_STRICTSETELEM_SUPER, 159, "strict-setelem-super", NULL, 1, 4, 1, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_DETECTING|JOF_CHECKSTRICT) \ \