@@ -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