@@ -79,14 +79,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
7979
8080      tree match  {
8181        case  Assign (lhs @  DesugaredSelect (qual, _), rhs) => 
82-           val  savedStackHeight  =  stackHeight 
82+           val  savedStackSize  =  stack.recordSize() 
8383          val  isStatic  =  lhs.symbol.isStaticMember
8484          if  (! isStatic) {
85-             genLoadQualifier(lhs )
86-             stackHeight  +=   1 
85+             val   qualTK   =  genLoad(qual )
86+             stack.push(qualTK) 
8787          }
8888          genLoad(rhs, symInfoTK(lhs.symbol))
89-           stackHeight  =  savedStackHeight 
89+           stack.restoreSize(savedStackSize) 
9090          lineNumber(tree)
9191          //  receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError
9292          val  receiverClass  =  qual.tpe.typeSymbol
@@ -150,9 +150,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
150150          }
151151
152152          genLoad(larg, resKind)
153-           stackHeight  +=  resKind.size 
153+           stack.push(resKind) 
154154          genLoad(rarg, if  (isShift) INT  else  resKind)
155-           stackHeight  -=  resKind.size 
155+           stack.pop() 
156156
157157          (code : @ switch) match  {
158158            case  ADD  =>  bc add resKind
@@ -189,19 +189,19 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
189189      if  (isArrayGet(code)) {
190190        //  load argument on stack
191191        assert(args.length ==  1 , s " Too many arguments for array get operation:  $tree" );
192-         stackHeight  +=   1 
192+         stack.push(k) 
193193        genLoad(args.head, INT )
194-         stackHeight  -=   1 
194+         stack.pop() 
195195        generatedType =  k.asArrayBType.componentType
196196        bc.aload(elementType)
197197      }
198198      else  if  (isArraySet(code)) {
199199        val  List (a1, a2) =  args
200-         stackHeight  +=   1 
200+         stack.push(k) 
201201        genLoad(a1, INT )
202-         stackHeight  +=   1 
202+         stack.push( INT ) 
203203        genLoad(a2)
204-         stackHeight  -=   2 
204+         stack.pop( 2 ) 
205205        generatedType =  UNIT 
206206        bc.astore(elementType)
207207      } else  {
@@ -235,7 +235,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
235235          val  resKind        =  if  (hasUnitBranch) UNIT  else  tpeTK(tree)
236236
237237          val  postIf  =  new  asm.Label 
238-           genLoadTo(thenp, resKind, LoadDestination .Jump (postIf, stackHeight ))
238+           genLoadTo(thenp, resKind, LoadDestination .Jump (postIf, stack.recordSize() ))
239239          markProgramPoint(failure)
240240          genLoadTo(elsep, resKind, LoadDestination .FallThrough )
241241          markProgramPoint(postIf)
@@ -294,8 +294,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
294294      )
295295    }
296296
297-     def  genLoad (tree : Tree ):  Unit  =  {
298-       genLoad(tree, tpeTK(tree))
297+     def  genLoad (tree : Tree ):  BType  =  {
298+       val  generatedType  =  tpeTK(tree)
299+       genLoad(tree, generatedType)
300+       generatedType
299301    }
300302
301303    /*  Generate code for trees that produce values on the stack */ 
@@ -364,6 +366,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
364366            case  t @  Ident (_) =>  (t, Nil )
365367          }
366368
369+           val  savedStackSize  =  stack.recordSize()
367370          if  (! fun.symbol.isStaticMember) {
368371            //  load receiver of non-static implementation of lambda
369372
@@ -372,10 +375,12 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
372375            //  AbstractValidatingLambdaMetafactory.validateMetafactoryArgs
373376
374377            val  DesugaredSelect (prefix, _) =  fun : @ unchecked
375-             genLoad(prefix)
378+             val  prefixTK  =  genLoad(prefix)
379+             stack.push(prefixTK)
376380          }
377381
378382          genLoadArguments(env, fun.symbol.info.firstParamTypes map toTypeKind)
383+           stack.restoreSize(savedStackSize)
379384          generatedType =  genInvokeDynamicLambda(NoSymbol , fun.symbol, env.size, functionalInterface)
380385
381386        case  app @  Apply (_, _) => 
@@ -494,9 +499,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
494499      dest match 
495500        case  LoadDestination .FallThrough  => 
496501          ()
497-         case  LoadDestination .Jump (label, targetStackHeight ) => 
498-           if  targetStackHeight  <  stackHeight  then 
499-              val   stackDiff  =  stackHeight  -  targetStackHeight 
502+         case  LoadDestination .Jump (label, targetStackSize ) => 
503+           val   stackDiff   =  stack.heightDiffWrt(targetStackSize) 
504+           if   stackDiff !=   0   then 
500505            if  expectedType ==  UNIT  then 
501506              bc dropMany stackDiff
502507            else 
@@ -599,7 +604,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
599604      if  dest ==  LoadDestination .FallThrough  then 
600605        val  resKind  =  tpeTK(tree)
601606        val  jumpTarget  =  new  asm.Label 
602-         registerJumpDest(labelSym, resKind, LoadDestination .Jump (jumpTarget, stackHeight ))
607+         registerJumpDest(labelSym, resKind, LoadDestination .Jump (jumpTarget, stack.recordSize() ))
603608        genLoad(expr, resKind)
604609        markProgramPoint(jumpTarget)
605610        resKind
@@ -657,7 +662,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
657662      markProgramPoint(loop)
658663
659664      if  isInfinite then 
660-         val  dest  =  LoadDestination .Jump (loop, stackHeight )
665+         val  dest  =  LoadDestination .Jump (loop, stack.recordSize() )
661666        genLoadTo(body, UNIT , dest)
662667        dest
663668      else 
@@ -672,7 +677,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
672677            val  failure  =  new  asm.Label 
673678            genCond(cond, success, failure, targetIfNoJump =  success)
674679            markProgramPoint(success)
675-             genLoadTo(body, UNIT , LoadDestination .Jump (loop, stackHeight ))
680+             genLoadTo(body, UNIT , LoadDestination .Jump (loop, stack.recordSize() ))
676681            markProgramPoint(failure)
677682        end match 
678683        LoadDestination .FallThrough 
@@ -765,10 +770,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
765770          //  on the stack (contrary to what the type in the AST says).
766771
767772          //  scala/bug#10290: qual can be `this.$outer()` (not just `this`), so we call genLoad (not just ALOAD_0)
768-           genLoad(superQual)
769-           stackHeight  +=   1 
773+           val   superQualTK   =   genLoad(superQual)
774+           stack.push(superQualTK) 
770775          genLoadArguments(args, paramTKs(app))
771-           stackHeight  -=   1 
776+           stack.pop() 
772777          generatedType =  genCallMethod(fun.symbol, InvokeStyle .Super , app.span)
773778
774779        //  'new' constructor call: Note: since constructors are
@@ -790,9 +795,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
790795              assert(classBTypeFromSymbol(ctor.owner) ==  rt, s " Symbol  ${ctor.owner.showFullName} is different from  $rt" )
791796              mnode.visitTypeInsn(asm.Opcodes .NEW , rt.internalName)
792797              bc dup generatedType
793-               stackHeight +=  2 
798+               stack.push(rt)
799+               stack.push(rt)
794800              genLoadArguments(args, paramTKs(app))
795-               stackHeight  -=   2 
801+               stack.pop( 2 ) 
796802              genCallMethod(ctor, InvokeStyle .Special , app.span)
797803
798804            case  _ => 
@@ -825,12 +831,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
825831              else  if  (app.hasAttachment(BCodeHelpers .UseInvokeSpecial )) InvokeStyle .Special 
826832              else  InvokeStyle .Virtual 
827833
828-             val  savedStackHeight  =  stackHeight 
834+             val  savedStackSize  =  stack.recordSize() 
829835            if  invokeStyle.hasInstance then 
830-               genLoadQualifier(fun)
831-               stackHeight +=  1 
836+               stack.push(genLoadQualifier(fun))
832837            genLoadArguments(args, paramTKs(app))
833-             stackHeight  =  savedStackHeight 
838+             stack.restoreSize(savedStackSize) 
834839
835840            val  DesugaredSelect (qual, name) =  fun : @ unchecked //  fun is a Select, also checked in genLoadQualifier
836841            val  isArrayClone  =  name ==  nme.clone_ &&  qual.tpe.widen.isInstanceOf [JavaArrayType ]
@@ -888,7 +893,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
888893      bc iconst   elems.length
889894      bc newarray elmKind
890895
891-       stackHeight +=  3  //  during the genLoad below, there is the result, its dup, and the index
896+       //  during the genLoad below, there is the result, its dup, and the index
897+       stack.push(generatedType)
898+       stack.push(generatedType)
899+       stack.push(INT )
892900
893901      var  i  =  0 
894902      var  rest  =  elems
@@ -901,7 +909,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
901909        i =  i +  1 
902910      }
903911
904-       stackHeight  -=   3 
912+       stack.pop( 3 ) 
905913
906914      generatedType
907915    }
@@ -917,7 +925,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
917925      val  (generatedType, postMatch, postMatchDest) = 
918926        if  dest ==  LoadDestination .FallThrough  then 
919927          val  postMatch  =  new  asm.Label 
920-           (tpeTK(tree), postMatch, LoadDestination .Jump (postMatch, stackHeight ))
928+           (tpeTK(tree), postMatch, LoadDestination .Jump (postMatch, stack.recordSize() ))
921929        else 
922930          (expectedType, null , dest)
923931
@@ -1179,7 +1187,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
11791187    }
11801188
11811189    /*  Emit code to Load the qualifier of `tree` on top of the stack. */ 
1182-     def  genLoadQualifier (tree : Tree ):  Unit  =  {
1190+     def  genLoadQualifier (tree : Tree ):  BType  =  {
11831191      lineNumber(tree)
11841192      tree match  {
11851193        case  DesugaredSelect (qualifier, _) =>  genLoad(qualifier)
@@ -1188,6 +1196,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
11881196            case  Some (sel) =>  genLoadQualifier(sel)
11891197            case  None  => 
11901198              assert(t.symbol.owner ==  this .claszSymbol)
1199+               UNIT 
11911200          }
11921201        case  _                    =>  abort(s " Unknown qualifier  $tree" )
11931202      }
@@ -1200,14 +1209,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
12001209            btpes match 
12011210              case  btpe ::  btpes1 => 
12021211                genLoad(arg, btpe)
1203-                 stackHeight  +=  btpe.size 
1212+                 stack.push(btpe) 
12041213                loop(args1, btpes1)
12051214              case  _ => 
12061215          case  _ => 
12071216
1208-       val  savedStackHeight  =  stackHeight 
1217+       val  savedStackSize  =  stack.recordSize() 
12091218      loop(args, btpes)
1210-       stackHeight  =  savedStackHeight 
1219+       stack.restoreSize(savedStackSize) 
12111220    end  genLoadArguments 
12121221
12131222    def  genLoadModule (tree : Tree ):  BType  =  {
@@ -1307,13 +1316,13 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
13071316            }.sum
13081317            bc.genNewStringBuilder(approxBuilderSize)
13091318
1310-             stackHeight  +=   1  //  during the genLoad below, there is a reference to the StringBuilder on the stack
1319+             stack.push(jlStringBuilderRef)  //  during the genLoad below, there is a reference to the StringBuilder on the stack
13111320            for  (elem <-  concatArguments) {
13121321              val  elemType  =  tpeTK(elem)
13131322              genLoad(elem, elemType)
13141323              bc.genStringBuilderAppend(elemType)
13151324            }
1316-             stackHeight  -=   1 
1325+             stack.pop() 
13171326
13181327            bc.genStringBuilderEnd
13191328          } else  {
@@ -1331,15 +1340,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
13311340            var  totalArgSlots  =  0 
13321341            var  countConcats  =  1      //  ie. 1 + how many times we spilled
13331342
1334-             val  savedStackHeight  =  stackHeight 
1343+             val  savedStackSize  =  stack.recordSize() 
13351344
13361345            for  (elem <-  concatArguments) {
13371346              val  tpe  =  tpeTK(elem)
13381347              val  elemSlots  =  tpe.size
13391348
13401349              //  Unlikely spill case
13411350              if  (totalArgSlots +  elemSlots >=  MaxIndySlots ) {
1342-                 stackHeight =  savedStackHeight +  countConcats
1351+                 stack.restoreSize(savedStackSize)
1352+                 for  _ <-  0  until countConcats do 
1353+                   stack.push(StringRef )
13431354                bc.genIndyStringConcat(recipe.toString, argTypes.result(), constVals.result())
13441355                countConcats +=  1 
13451356                totalArgSlots =  0 
@@ -1364,10 +1375,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
13641375                  val  tpe  =  tpeTK(elem)
13651376                  argTypes +=  tpe.toASMType
13661377                  genLoad(elem, tpe)
1367-                   stackHeight  +=   1 
1378+                   stack.push(tpe) 
13681379              }
13691380            }
1370-             stackHeight  =  savedStackHeight 
1381+             stack.restoreSize(savedStackSize) 
13711382            bc.genIndyStringConcat(recipe.toString, argTypes.result(), constVals.result())
13721383
13731384            //  If we spilled, generate one final concat
@@ -1562,9 +1573,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
15621573        } else  {
15631574          val  tk  =  tpeTK(l).maxType(tpeTK(r))
15641575          genLoad(l, tk)
1565-           stackHeight  +=  tk.size 
1576+           stack.push(tk) 
15661577          genLoad(r, tk)
1567-           stackHeight  -=  tk.size 
1578+           stack.pop() 
15681579          genCJUMP(success, failure, op, tk, targetIfNoJump)
15691580        }
15701581      }
@@ -1679,9 +1690,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
16791690        }
16801691
16811692        genLoad(l, ObjectRef )
1682-         stackHeight  +=   1 
1693+         stack.push( ObjectRef ) 
16831694        genLoad(r, ObjectRef )
1684-         stackHeight  -=   1 
1695+         stack.pop() 
16851696        genCallMethod(equalsMethod, InvokeStyle .Static )
16861697        genCZJUMP(success, failure, Primitives .NE , BOOL , targetIfNoJump)
16871698      }
@@ -1697,9 +1708,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
16971708        } else  if  (isNonNullExpr(l)) {
16981709          //  SI-7852 Avoid null check if L is statically non-null.
16991710          genLoad(l, ObjectRef )
1700-           stackHeight  +=   1 
1711+           stack.push( ObjectRef ) 
17011712          genLoad(r, ObjectRef )
1702-           stackHeight  -=   1 
1713+           stack.pop() 
17031714          genCallMethod(defn.Any_equals , InvokeStyle .Virtual )
17041715          genCZJUMP(success, failure, Primitives .NE , BOOL , targetIfNoJump)
17051716        } else  {
@@ -1709,9 +1720,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
17091720          val  lNonNull  =  new  asm.Label 
17101721
17111722          genLoad(l, ObjectRef )
1712-           stackHeight  +=   1 
1723+           stack.push( ObjectRef ) 
17131724          genLoad(r, ObjectRef )
1714-           stackHeight  -=   1 
1725+           stack.pop() 
17151726          locals.store(eqEqTempLocal)
17161727          bc dup ObjectRef 
17171728          genCZJUMP(lNull, lNonNull, Primitives .EQ , ObjectRef , targetIfNoJump =  lNull)
0 commit comments