diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala index 4aa60d973264..699a4cc787eb 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala @@ -11,6 +11,7 @@ object ClassfileConstants { inline val JAVA_MINOR_VERSION = 3 inline val JAVA8_MAJOR_VERSION = 52 + inline val JAVA_LATEST_MAJOR_VERSION = 65 /** (see http://java.sun.com/docs/books/jvms/second_edition/jvms-clarify.html) * diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index 349dbc445971..698efb058570 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -57,6 +57,22 @@ object ClassfileParser { } } + private[classfile] def parseHeader(classfile: AbstractFile)(using in: DataReader): Unit = { + val magic = in.nextInt + if (magic != JAVA_MAGIC) + throw new IOException(s"class file '${classfile}' has wrong magic number 0x${toHexString(magic)}, should be 0x${toHexString(JAVA_MAGIC)}") + val minorVersion = in.nextChar.toInt + val majorVersion = in.nextChar.toInt + if ((majorVersion < JAVA_MAJOR_VERSION) || + ((majorVersion == JAVA_MAJOR_VERSION) && + (minorVersion < JAVA_MINOR_VERSION))) + throw new IOException( + s"class file '${classfile}' has unknown version $majorVersion.$minorVersion, should be at least $JAVA_MAJOR_VERSION.$JAVA_MINOR_VERSION") + if majorVersion > JAVA_LATEST_MAJOR_VERSION then + throw new IOException( + s"class file '${classfile}' has unknown version $majorVersion.$minorVersion, and was compiled by a newer JDK than supported by this Scala version, please update to a newer Scala version.") + } + abstract class AbstractConstantPool(using in: DataReader) { protected val len = in.nextChar protected val starts = new Array[Int](len) @@ -259,7 +275,7 @@ class ClassfileParser( def run()(using Context): Option[Embedded] = try ctx.base.reusableDataReader.withInstance { reader => implicit val reader2 = reader.reset(classfile) report.debuglog("[class] >> " + classRoot.fullName) - parseHeader() + parseHeader(classfile) this.pool = new ConstantPool val res = parseClass() this.pool = null @@ -273,19 +289,6 @@ class ClassfileParser( |${Option(e.getMessage).getOrElse("")}""") } - private def parseHeader()(using in: DataReader): Unit = { - val magic = in.nextInt - if (magic != JAVA_MAGIC) - throw new IOException(s"class file '${classfile}' has wrong magic number 0x${toHexString(magic)}, should be 0x${toHexString(JAVA_MAGIC)}") - val minorVersion = in.nextChar.toInt - val majorVersion = in.nextChar.toInt - if ((majorVersion < JAVA_MAJOR_VERSION) || - ((majorVersion == JAVA_MAJOR_VERSION) && - (minorVersion < JAVA_MINOR_VERSION))) - throw new IOException( - s"class file '${classfile}' has unknown version $majorVersion.$minorVersion, should be at least $JAVA_MAJOR_VERSION.$JAVA_MINOR_VERSION") - } - /** Return the class symbol of the given name. */ def classNameToSymbol(name: Name)(using Context): Symbol = val nameStr = name.toString diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileTastyUUIDParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileTastyUUIDParser.scala index 4c4885fd5313..1a3887abeae5 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileTastyUUIDParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileTastyUUIDParser.scala @@ -26,7 +26,7 @@ class ClassfileTastyUUIDParser(classfile: AbstractFile)(ictx: Context) { def checkTastyUUID(tastyUUID: UUID)(using Context): Unit = try ctx.base.reusableDataReader.withInstance { reader => implicit val reader2 = reader.reset(classfile) - parseHeader() + ClassfileParser.parseHeader(classfile) this.pool = new ConstantPool checkTastyAttr(tastyUUID) this.pool = null @@ -39,19 +39,6 @@ class ClassfileTastyUUIDParser(classfile: AbstractFile)(ictx: Context) { |${Option(e.getMessage).getOrElse("")}""") } - private def parseHeader()(using in: DataReader): Unit = { - val magic = in.nextInt - if (magic != JAVA_MAGIC) - throw new IOException(s"class file '${classfile}' has wrong magic number 0x${toHexString(magic)}, should be 0x${toHexString(JAVA_MAGIC)}") - val minorVersion = in.nextChar.toInt - val majorVersion = in.nextChar.toInt - if ((majorVersion < JAVA_MAJOR_VERSION) || - ((majorVersion == JAVA_MAJOR_VERSION) && - (minorVersion < JAVA_MINOR_VERSION))) - throw new IOException( - s"class file '${classfile}' has unknown version $majorVersion.$minorVersion, should be at least $JAVA_MAJOR_VERSION.$JAVA_MINOR_VERSION") - } - private def checkTastyAttr(tastyUUID: UUID)(using ctx: Context, in: DataReader): Unit = { in.nextChar // jflags in.nextChar // nameIdx