Skip to content

Commit 0516595

Browse files
committed
Include Long/Double size in max param count
1 parent 7444ea8 commit 0516595

File tree

5 files changed

+68
-65
lines changed

5 files changed

+68
-65
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,20 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
613613
for (p <- params) locals.makeLocal(p.symbol)
614614
// debug assert((params.map(p => locals(p.symbol).tk)) == asmMethodType(methSymbol).getArgumentTypes.toList, "debug")
615615

616-
if (params.size > MaximumJvmParameters) {
617-
// scala/bug#7324
618-
reporter.error(methSymbol.pos, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.")
616+
// scala/bug#7324
617+
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3
618+
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.11
619+
// https://docs.oracle.com/javase/specs/jvms/se20/html/jvms-4.html#jvms-4.11
620+
val paramsLength = params.foldLeft(0) { (sum, p) =>
621+
val i = p.symbol.info.typeSymbol match {
622+
case definitions.LongClass | definitions.DoubleClass => 2
623+
case _ => 1
624+
}
625+
sum + i
626+
}
627+
if (paramsLength > MaximumJvmParameters) {
628+
val info = if (paramsLength == params.length) "" else " (Long and Double count as 2)"
629+
reporter.error(methSymbol.pos, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters$info.")
619630
return
620631
}
621632

src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ final class RichClassLoader(private val self: JClassLoader) extends AnyVal {
4343
def tryToInitializeClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, initialize = true)
4444

4545
private def tryClass[T <: AnyRef](path: String, initialize: Boolean): Option[Class[T]] =
46-
catching(classOf[ClassNotFoundException], classOf[SecurityException]) opt
46+
catching(classOf[ClassFormatError], classOf[ClassNotFoundException], classOf[SecurityException]) opt
4747
Class.forName(path, initialize, self).asInstanceOf[Class[T]]
4848

4949
/** Create an instance of a class with this classloader */

test/files/neg/t7324.check

Lines changed: 0 additions & 4 deletions
This file was deleted.

test/files/neg/t7324.scala

Lines changed: 0 additions & 57 deletions
This file was deleted.

test/files/run/t7324.scala

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
2+
import org.junit.Assert.{assertEquals, assertFalse, assertTrue}
3+
import scala.reflect.internal.util.ScalaClassLoader
4+
import scala.tools.partest.StoreReporterDirectTest
5+
6+
object Test extends StoreReporterDirectTest {
7+
8+
//override def extraSettings: String = "-usejavacp -Xlint"
9+
10+
def code = classOfArgs(254)
11+
12+
def show() = {
13+
val compiler = newCompiler()
14+
assertTrue(compileString(compiler)(code))
15+
load()
16+
assertFalse(compileString(compiler)(classOfArgs(255)))
17+
check()
18+
assertTrue(compileString(compiler)(methodOfArgs(254)))
19+
load()
20+
assertFalse(compileString(compiler)(methodOfArgs(255)))
21+
check()
22+
assertFalse(compileString(compiler)(methodOfArgs(254, "Long")))
23+
check(isLongly = true)
24+
assertTrue(compileString(compiler)(methodOfArgs(254/2, "Long")))
25+
load()
26+
assertFalse(compileString(compiler)(methodOfArgs(254/2 + 1, "Long")))
27+
check(isLongly = true)
28+
assertFalse(compileString(compiler)(methodOfArgs(254, "Double")))
29+
check(isLongly = true)
30+
assertTrue(compileString(compiler)(methodOfArgs(254/2, "Double")))
31+
load()
32+
assertFalse(compileString(compiler)(methodOfArgs(254/2 + 1, "Double")))
33+
check(isLongly = true)
34+
}
35+
36+
private def check(isLongly: Boolean = false) = {
37+
assertTrue("Expected diagnostics", storeReporter.infos.nonEmpty)
38+
val expected =
39+
if (isLongly) "Platform restriction: a parameter list's length cannot exceed 254 (Long and Double count as 2)."
40+
else "Platform restriction: a parameter list's length cannot exceed 254."
41+
storeReporter.infos.foreach(info => assertEquals(expected, info.msg))
42+
}
43+
private def load() = {
44+
val loader = ScalaClassLoader.fromURLs(Seq(testOutput.jfile.toURI.toURL))
45+
assertFalse("Expected loadable class B", loader.tryToLoadClass("B").isEmpty)
46+
}
47+
48+
private def classOfArgs(n: Int, t: String = "Int") = s"class B${mkArgs(n, t)}"
49+
50+
private def methodOfArgs(n: Int, t: String = "Int") = s"class B { def m${mkArgs(n, t)}: Unit = () }"
51+
52+
private def mkArgs(n: Int, t: String) = 1.to(n).map(i => s"x$i: $t").mkString("(",",",")")
53+
}

0 commit comments

Comments
 (0)