@@ -79,14 +79,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
79
79
80
80
tree match {
81
81
case Assign (lhs @ DesugaredSelect (qual, _), rhs) =>
82
- val savedStackHeight = stackHeight
82
+ val savedStackSize = stack.recordSize()
83
83
val isStatic = lhs.symbol.isStaticMember
84
84
if (! isStatic) {
85
- genLoadQualifier(lhs )
86
- stackHeight += 1
85
+ val qualTK = genLoad(qual )
86
+ stack.push(qualTK)
87
87
}
88
88
genLoad(rhs, symInfoTK(lhs.symbol))
89
- stackHeight = savedStackHeight
89
+ stack.restoreSize(savedStackSize)
90
90
lineNumber(tree)
91
91
// receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError
92
92
val receiverClass = qual.tpe.typeSymbol
@@ -150,9 +150,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
150
150
}
151
151
152
152
genLoad(larg, resKind)
153
- stackHeight += resKind.size
153
+ stack.push(resKind)
154
154
genLoad(rarg, if (isShift) INT else resKind)
155
- stackHeight -= resKind.size
155
+ stack.pop()
156
156
157
157
(code : @ switch) match {
158
158
case ADD => bc add resKind
@@ -189,19 +189,19 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
189
189
if (isArrayGet(code)) {
190
190
// load argument on stack
191
191
assert(args.length == 1 , s " Too many arguments for array get operation: $tree" );
192
- stackHeight += 1
192
+ stack.push(k)
193
193
genLoad(args.head, INT )
194
- stackHeight -= 1
194
+ stack.pop()
195
195
generatedType = k.asArrayBType.componentType
196
196
bc.aload(elementType)
197
197
}
198
198
else if (isArraySet(code)) {
199
199
val List (a1, a2) = args
200
- stackHeight += 1
200
+ stack.push(k)
201
201
genLoad(a1, INT )
202
- stackHeight += 1
202
+ stack.push( INT )
203
203
genLoad(a2)
204
- stackHeight -= 2
204
+ stack.pop( 2 )
205
205
generatedType = UNIT
206
206
bc.astore(elementType)
207
207
} else {
@@ -235,7 +235,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
235
235
val resKind = if (hasUnitBranch) UNIT else tpeTK(tree)
236
236
237
237
val postIf = new asm.Label
238
- genLoadTo(thenp, resKind, LoadDestination .Jump (postIf, stackHeight ))
238
+ genLoadTo(thenp, resKind, LoadDestination .Jump (postIf, stack.recordSize() ))
239
239
markProgramPoint(failure)
240
240
genLoadTo(elsep, resKind, LoadDestination .FallThrough )
241
241
markProgramPoint(postIf)
@@ -294,8 +294,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
294
294
)
295
295
}
296
296
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
299
301
}
300
302
301
303
/* Generate code for trees that produce values on the stack */
@@ -364,6 +366,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
364
366
case t @ Ident (_) => (t, Nil )
365
367
}
366
368
369
+ val savedStackSize = stack.recordSize()
367
370
if (! fun.symbol.isStaticMember) {
368
371
// load receiver of non-static implementation of lambda
369
372
@@ -372,10 +375,12 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
372
375
// AbstractValidatingLambdaMetafactory.validateMetafactoryArgs
373
376
374
377
val DesugaredSelect (prefix, _) = fun : @ unchecked
375
- genLoad(prefix)
378
+ val prefixTK = genLoad(prefix)
379
+ stack.push(prefixTK)
376
380
}
377
381
378
382
genLoadArguments(env, fun.symbol.info.firstParamTypes map toTypeKind)
383
+ stack.restoreSize(savedStackSize)
379
384
generatedType = genInvokeDynamicLambda(NoSymbol , fun.symbol, env.size, functionalInterface)
380
385
381
386
case app @ Apply (_, _) =>
@@ -494,9 +499,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
494
499
dest match
495
500
case LoadDestination .FallThrough =>
496
501
()
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
500
505
if expectedType == UNIT then
501
506
bc dropMany stackDiff
502
507
else
@@ -599,7 +604,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
599
604
if dest == LoadDestination .FallThrough then
600
605
val resKind = tpeTK(tree)
601
606
val jumpTarget = new asm.Label
602
- registerJumpDest(labelSym, resKind, LoadDestination .Jump (jumpTarget, stackHeight ))
607
+ registerJumpDest(labelSym, resKind, LoadDestination .Jump (jumpTarget, stack.recordSize() ))
603
608
genLoad(expr, resKind)
604
609
markProgramPoint(jumpTarget)
605
610
resKind
@@ -657,7 +662,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
657
662
markProgramPoint(loop)
658
663
659
664
if isInfinite then
660
- val dest = LoadDestination .Jump (loop, stackHeight )
665
+ val dest = LoadDestination .Jump (loop, stack.recordSize() )
661
666
genLoadTo(body, UNIT , dest)
662
667
dest
663
668
else
@@ -672,7 +677,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
672
677
val failure = new asm.Label
673
678
genCond(cond, success, failure, targetIfNoJump = success)
674
679
markProgramPoint(success)
675
- genLoadTo(body, UNIT , LoadDestination .Jump (loop, stackHeight ))
680
+ genLoadTo(body, UNIT , LoadDestination .Jump (loop, stack.recordSize() ))
676
681
markProgramPoint(failure)
677
682
end match
678
683
LoadDestination .FallThrough
@@ -765,10 +770,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
765
770
// on the stack (contrary to what the type in the AST says).
766
771
767
772
// 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)
770
775
genLoadArguments(args, paramTKs(app))
771
- stackHeight -= 1
776
+ stack.pop()
772
777
generatedType = genCallMethod(fun.symbol, InvokeStyle .Super , app.span)
773
778
774
779
// 'new' constructor call: Note: since constructors are
@@ -790,9 +795,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
790
795
assert(classBTypeFromSymbol(ctor.owner) == rt, s " Symbol ${ctor.owner.showFullName} is different from $rt" )
791
796
mnode.visitTypeInsn(asm.Opcodes .NEW , rt.internalName)
792
797
bc dup generatedType
793
- stackHeight += 2
798
+ stack.push(rt)
799
+ stack.push(rt)
794
800
genLoadArguments(args, paramTKs(app))
795
- stackHeight -= 2
801
+ stack.pop( 2 )
796
802
genCallMethod(ctor, InvokeStyle .Special , app.span)
797
803
798
804
case _ =>
@@ -825,12 +831,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
825
831
else if (app.hasAttachment(BCodeHelpers .UseInvokeSpecial )) InvokeStyle .Special
826
832
else InvokeStyle .Virtual
827
833
828
- val savedStackHeight = stackHeight
834
+ val savedStackSize = stack.recordSize()
829
835
if invokeStyle.hasInstance then
830
- genLoadQualifier(fun)
831
- stackHeight += 1
836
+ stack.push(genLoadQualifier(fun))
832
837
genLoadArguments(args, paramTKs(app))
833
- stackHeight = savedStackHeight
838
+ stack.restoreSize(savedStackSize)
834
839
835
840
val DesugaredSelect (qual, name) = fun : @ unchecked // fun is a Select, also checked in genLoadQualifier
836
841
val isArrayClone = name == nme.clone_ && qual.tpe.widen.isInstanceOf [JavaArrayType ]
@@ -888,7 +893,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
888
893
bc iconst elems.length
889
894
bc newarray elmKind
890
895
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 )
892
900
893
901
var i = 0
894
902
var rest = elems
@@ -901,7 +909,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
901
909
i = i + 1
902
910
}
903
911
904
- stackHeight -= 3
912
+ stack.pop( 3 )
905
913
906
914
generatedType
907
915
}
@@ -917,7 +925,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
917
925
val (generatedType, postMatch, postMatchDest) =
918
926
if dest == LoadDestination .FallThrough then
919
927
val postMatch = new asm.Label
920
- (tpeTK(tree), postMatch, LoadDestination .Jump (postMatch, stackHeight ))
928
+ (tpeTK(tree), postMatch, LoadDestination .Jump (postMatch, stack.recordSize() ))
921
929
else
922
930
(expectedType, null , dest)
923
931
@@ -1179,7 +1187,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1179
1187
}
1180
1188
1181
1189
/* 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 = {
1183
1191
lineNumber(tree)
1184
1192
tree match {
1185
1193
case DesugaredSelect (qualifier, _) => genLoad(qualifier)
@@ -1188,6 +1196,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1188
1196
case Some (sel) => genLoadQualifier(sel)
1189
1197
case None =>
1190
1198
assert(t.symbol.owner == this .claszSymbol)
1199
+ UNIT
1191
1200
}
1192
1201
case _ => abort(s " Unknown qualifier $tree" )
1193
1202
}
@@ -1200,14 +1209,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1200
1209
btpes match
1201
1210
case btpe :: btpes1 =>
1202
1211
genLoad(arg, btpe)
1203
- stackHeight += btpe.size
1212
+ stack.push(btpe)
1204
1213
loop(args1, btpes1)
1205
1214
case _ =>
1206
1215
case _ =>
1207
1216
1208
- val savedStackHeight = stackHeight
1217
+ val savedStackSize = stack.recordSize()
1209
1218
loop(args, btpes)
1210
- stackHeight = savedStackHeight
1219
+ stack.restoreSize(savedStackSize)
1211
1220
end genLoadArguments
1212
1221
1213
1222
def genLoadModule (tree : Tree ): BType = {
@@ -1307,13 +1316,13 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1307
1316
}.sum
1308
1317
bc.genNewStringBuilder(approxBuilderSize)
1309
1318
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
1311
1320
for (elem <- concatArguments) {
1312
1321
val elemType = tpeTK(elem)
1313
1322
genLoad(elem, elemType)
1314
1323
bc.genStringBuilderAppend(elemType)
1315
1324
}
1316
- stackHeight -= 1
1325
+ stack.pop()
1317
1326
1318
1327
bc.genStringBuilderEnd
1319
1328
} else {
@@ -1331,15 +1340,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1331
1340
var totalArgSlots = 0
1332
1341
var countConcats = 1 // ie. 1 + how many times we spilled
1333
1342
1334
- val savedStackHeight = stackHeight
1343
+ val savedStackSize = stack.recordSize()
1335
1344
1336
1345
for (elem <- concatArguments) {
1337
1346
val tpe = tpeTK(elem)
1338
1347
val elemSlots = tpe.size
1339
1348
1340
1349
// Unlikely spill case
1341
1350
if (totalArgSlots + elemSlots >= MaxIndySlots ) {
1342
- stackHeight = savedStackHeight + countConcats
1351
+ stack.restoreSize(savedStackSize)
1352
+ for _ <- 0 until countConcats do
1353
+ stack.push(StringRef )
1343
1354
bc.genIndyStringConcat(recipe.toString, argTypes.result(), constVals.result())
1344
1355
countConcats += 1
1345
1356
totalArgSlots = 0
@@ -1364,10 +1375,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1364
1375
val tpe = tpeTK(elem)
1365
1376
argTypes += tpe.toASMType
1366
1377
genLoad(elem, tpe)
1367
- stackHeight += 1
1378
+ stack.push(tpe)
1368
1379
}
1369
1380
}
1370
- stackHeight = savedStackHeight
1381
+ stack.restoreSize(savedStackSize)
1371
1382
bc.genIndyStringConcat(recipe.toString, argTypes.result(), constVals.result())
1372
1383
1373
1384
// If we spilled, generate one final concat
@@ -1562,9 +1573,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1562
1573
} else {
1563
1574
val tk = tpeTK(l).maxType(tpeTK(r))
1564
1575
genLoad(l, tk)
1565
- stackHeight += tk.size
1576
+ stack.push(tk)
1566
1577
genLoad(r, tk)
1567
- stackHeight -= tk.size
1578
+ stack.pop()
1568
1579
genCJUMP(success, failure, op, tk, targetIfNoJump)
1569
1580
}
1570
1581
}
@@ -1679,9 +1690,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1679
1690
}
1680
1691
1681
1692
genLoad(l, ObjectRef )
1682
- stackHeight += 1
1693
+ stack.push( ObjectRef )
1683
1694
genLoad(r, ObjectRef )
1684
- stackHeight -= 1
1695
+ stack.pop()
1685
1696
genCallMethod(equalsMethod, InvokeStyle .Static )
1686
1697
genCZJUMP(success, failure, Primitives .NE , BOOL , targetIfNoJump)
1687
1698
}
@@ -1697,9 +1708,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1697
1708
} else if (isNonNullExpr(l)) {
1698
1709
// SI-7852 Avoid null check if L is statically non-null.
1699
1710
genLoad(l, ObjectRef )
1700
- stackHeight += 1
1711
+ stack.push( ObjectRef )
1701
1712
genLoad(r, ObjectRef )
1702
- stackHeight -= 1
1713
+ stack.pop()
1703
1714
genCallMethod(defn.Any_equals , InvokeStyle .Virtual )
1704
1715
genCZJUMP(success, failure, Primitives .NE , BOOL , targetIfNoJump)
1705
1716
} else {
@@ -1709,9 +1720,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
1709
1720
val lNonNull = new asm.Label
1710
1721
1711
1722
genLoad(l, ObjectRef )
1712
- stackHeight += 1
1723
+ stack.push( ObjectRef )
1713
1724
genLoad(r, ObjectRef )
1714
- stackHeight -= 1
1725
+ stack.pop()
1715
1726
locals.store(eqEqTempLocal)
1716
1727
bc dup ObjectRef
1717
1728
genCZJUMP(lNull, lNonNull, Primitives .EQ , ObjectRef , targetIfNoJump = lNull)
0 commit comments