diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 1eba6c0b1bf8..89db584a5905 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1713,26 +1713,23 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genCZJUMP(success, failure, Primitives.NE, BOOL, targetIfNoJump) } else { // l == r -> if (l eq null) r eq null else l.equals(r) - val eqEqTempLocal = locals.makeLocal(ObjectRef, nme.EQEQ_LOCAL_VAR.mangledString, defn.ObjectType, r.span) val lNull = new asm.Label val lNonNull = new asm.Label - genLoad(l, ObjectRef) + genLoad(r, ObjectRef) // load rhs --> (r) stack.push(ObjectRef) - genLoad(r, ObjectRef) + genLoad(l, ObjectRef) // load lhs --> (l,r) stack.pop() - locals.store(eqEqTempLocal) - bc dup ObjectRef - genCZJUMP(lNull, lNonNull, Primitives.EQ, ObjectRef, targetIfNoJump = lNull) + bc dup ObjectRef // duplicate top stack variable --> (l,l,r) + genCZJUMP(lNull, lNonNull, Primitives.EQ, ObjectRef, targetIfNoJump = lNull) // compare lhs with NULL --> (l,r) markProgramPoint(lNull) - bc drop ObjectRef - locals.load(eqEqTempLocal) - genCZJUMP(success, failure, Primitives.EQ, ObjectRef, targetIfNoJump = lNonNull) + bc drop ObjectRef // drop top stack variable --> (r) + genCZJUMP(success, failure, Primitives.EQ, ObjectRef, targetIfNoJump = lNonNull) // --> (-) markProgramPoint(lNonNull) - locals.load(eqEqTempLocal) - genCallMethod(defn.Any_equals, InvokeStyle.Virtual) + emit(asm.Opcodes.SWAP) //swap l and r for correct .equals ordering --> (r,l) + genCallMethod(defn.Any_equals, InvokeStyle.Virtual) // --> (-) genCZJUMP(success, failure, Primitives.NE, BOOL, targetIfNoJump) } } diff --git a/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala b/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala index 2e48b33ec624..898486927bf3 100644 --- a/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala +++ b/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala @@ -1168,7 +1168,7 @@ class DottyBytecodeTests extends DottyBytecodeTest { val m1Meth = getMethod(fooClass, "m1") - assertSameCode(m1Meth, List( + assertSameCode(m1Meth,List( VarOp(ALOAD, 1), VarOp(ASTORE, 2), VarOp(ALOAD, 2), @@ -1189,29 +1189,27 @@ class DottyBytecodeTests extends DottyBytecodeTest { VarOp(ILOAD, 5), Op(IRETURN), Label(19), + VarOp(ALOAD, 2), Field(GETSTATIC, "scala/package$", "MODULE$", "Lscala/package$;"), Invoke(INVOKEVIRTUAL, "scala/package$", "Nil", "()Lscala/collection/immutable/Nil$;", false), - VarOp(ALOAD, 2), - VarOp(ASTORE, 7), Op(DUP), - Jump(IFNONNULL, Label(31)), + Jump(IFNONNULL, Label(29)), Op(POP), - VarOp(ALOAD, 7), - Jump(IFNULL, Label(36)), - Jump(GOTO, Label(40)), - Label(31), - VarOp(ALOAD, 7), + Jump(IFNULL, Label(34)), + Jump(GOTO, Label(38)), + Label(29), + Op(SWAP), Invoke(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false), - Jump(IFEQ, Label(40)), - Label(36), + Jump(IFEQ, Label(38)), + Label(34), IntOp(BIPUSH, 20), Op(IRETURN), - Label(40), + Label(38), TypeOp(NEW, "scala/MatchError"), Op(DUP), VarOp(ALOAD, 2), Invoke(INVOKESPECIAL, "scala/MatchError", "", "(Ljava/lang/Object;)V", false), - Op(ATHROW), + Op(ATHROW) )) // ---------------