@@ -4,7 +4,7 @@ package jvm
44
55import scala .language .unsafeNulls
66
7- import scala .annotation .switch
7+ import scala .annotation .{ switch , tailrec }
88import scala .collection .mutable .SortedMap
99
1010import scala .tools .asm
@@ -79,9 +79,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
7979
8080 tree match {
8181 case Assign (lhs @ DesugaredSelect (qual, _), rhs) =>
82+ val savedStackHeight = stackHeight
8283 val isStatic = lhs.symbol.isStaticMember
83- if (! isStatic) { genLoadQualifier(lhs) }
84+ if (! isStatic) {
85+ genLoadQualifier(lhs)
86+ stackHeight += 1
87+ }
8488 genLoad(rhs, symInfoTK(lhs.symbol))
89+ stackHeight = savedStackHeight
8590 lineNumber(tree)
8691 // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError
8792 val receiverClass = qual.tpe.typeSymbol
@@ -145,7 +150,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
145150 }
146151
147152 genLoad(larg, resKind)
153+ stackHeight += resKind.size
148154 genLoad(rarg, if (isShift) INT else resKind)
155+ stackHeight -= resKind.size
149156
150157 (code : @ switch) match {
151158 case ADD => bc add resKind
@@ -182,14 +189,19 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
182189 if (isArrayGet(code)) {
183190 // load argument on stack
184191 assert(args.length == 1 , s " Too many arguments for array get operation: $tree" );
192+ stackHeight += 1
185193 genLoad(args.head, INT )
194+ stackHeight -= 1
186195 generatedType = k.asArrayBType.componentType
187196 bc.aload(elementType)
188197 }
189198 else if (isArraySet(code)) {
190199 val List (a1, a2) = args
200+ stackHeight += 1
191201 genLoad(a1, INT )
202+ stackHeight += 1
192203 genLoad(a2)
204+ stackHeight -= 2
193205 generatedType = UNIT
194206 bc.astore(elementType)
195207 } else {
@@ -223,7 +235,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
223235 val resKind = if (hasUnitBranch) UNIT else tpeTK(tree)
224236
225237 val postIf = new asm.Label
226- genLoadTo(thenp, resKind, LoadDestination .Jump (postIf))
238+ genLoadTo(thenp, resKind, LoadDestination .Jump (postIf, stackHeight ))
227239 markProgramPoint(failure)
228240 genLoadTo(elsep, resKind, LoadDestination .FallThrough )
229241 markProgramPoint(postIf)
@@ -482,7 +494,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
482494 dest match
483495 case LoadDestination .FallThrough =>
484496 ()
485- case LoadDestination .Jump (label) =>
497+ case LoadDestination .Jump (label, targetStackHeight) =>
498+ if targetStackHeight < stackHeight then
499+ val stackDiff = stackHeight - targetStackHeight
500+ if expectedType == UNIT then
501+ bc dropMany stackDiff
502+ else
503+ val loc = locals.makeTempLocal(expectedType)
504+ bc.store(loc.idx, expectedType)
505+ bc dropMany stackDiff
506+ bc.load(loc.idx, expectedType)
507+ end if
486508 bc goTo label
487509 case LoadDestination .Return =>
488510 bc emitRETURN returnType
@@ -577,7 +599,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
577599 if dest == LoadDestination .FallThrough then
578600 val resKind = tpeTK(tree)
579601 val jumpTarget = new asm.Label
580- registerJumpDest(labelSym, resKind, LoadDestination .Jump (jumpTarget))
602+ registerJumpDest(labelSym, resKind, LoadDestination .Jump (jumpTarget, stackHeight ))
581603 genLoad(expr, resKind)
582604 markProgramPoint(jumpTarget)
583605 resKind
@@ -635,7 +657,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
635657 markProgramPoint(loop)
636658
637659 if isInfinite then
638- val dest = LoadDestination .Jump (loop)
660+ val dest = LoadDestination .Jump (loop, stackHeight )
639661 genLoadTo(body, UNIT , dest)
640662 dest
641663 else
@@ -650,7 +672,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
650672 val failure = new asm.Label
651673 genCond(cond, success, failure, targetIfNoJump = success)
652674 markProgramPoint(success)
653- genLoadTo(body, UNIT , LoadDestination .Jump (loop))
675+ genLoadTo(body, UNIT , LoadDestination .Jump (loop, stackHeight ))
654676 markProgramPoint(failure)
655677 end match
656678 LoadDestination .FallThrough
@@ -744,7 +766,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
744766
745767 // scala/bug#10290: qual can be `this.$outer()` (not just `this`), so we call genLoad (not just ALOAD_0)
746768 genLoad(superQual)
769+ stackHeight += 1
747770 genLoadArguments(args, paramTKs(app))
771+ stackHeight -= 1
748772 generatedType = genCallMethod(fun.symbol, InvokeStyle .Super , app.span)
749773
750774 // 'new' constructor call: Note: since constructors are
@@ -766,7 +790,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
766790 assert(classBTypeFromSymbol(ctor.owner) == rt, s " Symbol ${ctor.owner.showFullName} is different from $rt" )
767791 mnode.visitTypeInsn(asm.Opcodes .NEW , rt.internalName)
768792 bc dup generatedType
793+ stackHeight += 2
769794 genLoadArguments(args, paramTKs(app))
795+ stackHeight -= 2
770796 genCallMethod(ctor, InvokeStyle .Special , app.span)
771797
772798 case _ =>
@@ -799,8 +825,12 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
799825 else if (app.hasAttachment(BCodeHelpers .UseInvokeSpecial )) InvokeStyle .Special
800826 else InvokeStyle .Virtual
801827
802- if (invokeStyle.hasInstance) genLoadQualifier(fun)
828+ val savedStackHeight = stackHeight
829+ if invokeStyle.hasInstance then
830+ genLoadQualifier(fun)
831+ stackHeight += 1
803832 genLoadArguments(args, paramTKs(app))
833+ stackHeight = savedStackHeight
804834
805835 val DesugaredSelect (qual, name) = fun : @ unchecked // fun is a Select, also checked in genLoadQualifier
806836 val isArrayClone = name == nme.clone_ && qual.tpe.widen.isInstanceOf [JavaArrayType ]
@@ -858,6 +888,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
858888 bc iconst elems.length
859889 bc newarray elmKind
860890
891+ stackHeight += 3 // during the genLoad below, there is the result, its dup, and the index
892+
861893 var i = 0
862894 var rest = elems
863895 while (! rest.isEmpty) {
@@ -869,6 +901,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
869901 i = i + 1
870902 }
871903
904+ stackHeight -= 3
905+
872906 generatedType
873907 }
874908
@@ -883,7 +917,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
883917 val (generatedType, postMatch, postMatchDest) =
884918 if dest == LoadDestination .FallThrough then
885919 val postMatch = new asm.Label
886- (tpeTK(tree), postMatch, LoadDestination .Jump (postMatch))
920+ (tpeTK(tree), postMatch, LoadDestination .Jump (postMatch, stackHeight ))
887921 else
888922 (expectedType, null , dest)
889923
@@ -1160,14 +1194,21 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
11601194 }
11611195
11621196 def genLoadArguments (args : List [Tree ], btpes : List [BType ]): Unit =
1163- args match
1164- case arg :: args1 =>
1165- btpes match
1166- case btpe :: btpes1 =>
1167- genLoad(arg, btpe)
1168- genLoadArguments(args1, btpes1)
1169- case _ =>
1170- case _ =>
1197+ @ tailrec def loop (args : List [Tree ], btpes : List [BType ]): Unit =
1198+ args match
1199+ case arg :: args1 =>
1200+ btpes match
1201+ case btpe :: btpes1 =>
1202+ genLoad(arg, btpe)
1203+ stackHeight += btpe.size
1204+ loop(args1, btpes1)
1205+ case _ =>
1206+ case _ =>
1207+
1208+ val savedStackHeight = stackHeight
1209+ loop(args, btpes)
1210+ stackHeight = savedStackHeight
1211+ end genLoadArguments
11711212
11721213 def genLoadModule (tree : Tree ): BType = {
11731214 val module = (
@@ -1266,11 +1307,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
12661307 }.sum
12671308 bc.genNewStringBuilder(approxBuilderSize)
12681309
1310+ stackHeight += 1 // during the genLoad below, there is a reference to the StringBuilder on the stack
12691311 for (elem <- concatArguments) {
12701312 val elemType = tpeTK(elem)
12711313 genLoad(elem, elemType)
12721314 bc.genStringBuilderAppend(elemType)
12731315 }
1316+ stackHeight -= 1
1317+
12741318 bc.genStringBuilderEnd
12751319 } else {
12761320
@@ -1287,12 +1331,15 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
12871331 var totalArgSlots = 0
12881332 var countConcats = 1 // ie. 1 + how many times we spilled
12891333
1334+ val savedStackHeight = stackHeight
1335+
12901336 for (elem <- concatArguments) {
12911337 val tpe = tpeTK(elem)
12921338 val elemSlots = tpe.size
12931339
12941340 // Unlikely spill case
12951341 if (totalArgSlots + elemSlots >= MaxIndySlots ) {
1342+ stackHeight = savedStackHeight + countConcats
12961343 bc.genIndyStringConcat(recipe.toString, argTypes.result(), constVals.result())
12971344 countConcats += 1
12981345 totalArgSlots = 0
@@ -1317,8 +1364,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
13171364 val tpe = tpeTK(elem)
13181365 argTypes += tpe.toASMType
13191366 genLoad(elem, tpe)
1367+ stackHeight += 1
13201368 }
13211369 }
1370+ stackHeight = savedStackHeight
13221371 bc.genIndyStringConcat(recipe.toString, argTypes.result(), constVals.result())
13231372
13241373 // If we spilled, generate one final concat
@@ -1513,7 +1562,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
15131562 } else {
15141563 val tk = tpeTK(l).maxType(tpeTK(r))
15151564 genLoad(l, tk)
1565+ stackHeight += tk.size
15161566 genLoad(r, tk)
1567+ stackHeight -= tk.size
15171568 genCJUMP(success, failure, op, tk, targetIfNoJump)
15181569 }
15191570 }
@@ -1628,7 +1679,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
16281679 }
16291680
16301681 genLoad(l, ObjectRef )
1682+ stackHeight += 1
16311683 genLoad(r, ObjectRef )
1684+ stackHeight -= 1
16321685 genCallMethod(equalsMethod, InvokeStyle .Static )
16331686 genCZJUMP(success, failure, Primitives .NE , BOOL , targetIfNoJump)
16341687 }
@@ -1644,7 +1697,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
16441697 } else if (isNonNullExpr(l)) {
16451698 // SI-7852 Avoid null check if L is statically non-null.
16461699 genLoad(l, ObjectRef )
1700+ stackHeight += 1
16471701 genLoad(r, ObjectRef )
1702+ stackHeight -= 1
16481703 genCallMethod(defn.Any_equals , InvokeStyle .Virtual )
16491704 genCZJUMP(success, failure, Primitives .NE , BOOL , targetIfNoJump)
16501705 } else {
@@ -1654,7 +1709,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
16541709 val lNonNull = new asm.Label
16551710
16561711 genLoad(l, ObjectRef )
1712+ stackHeight += 1
16571713 genLoad(r, ObjectRef )
1714+ stackHeight -= 1
16581715 locals.store(eqEqTempLocal)
16591716 bc dup ObjectRef
16601717 genCZJUMP(lNull, lNonNull, Primitives .EQ , ObjectRef , targetIfNoJump = lNull)
0 commit comments