Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita37a063

Browse files
som-snyttlrytz
authored andcommitted
-Yunsafe opens packages in jrt under --release
If no package names are provided, sun.misc is assumed,for the paradigmatic use case sun.misc.Unsafe.
1 parent0d0d219 commita37a063

File tree

8 files changed

+96
-35
lines changed

8 files changed

+96
-35
lines changed

‎src/compiler/scala/tools/nsc/Global.scala‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,10 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
146146
defoptimizerClassPath(base:ClassPath):ClassPath=
147147
basematch {
148148
caseAggregateClassPath(entries)if entries.head.isInstanceOf[CtSymClassPath]=>
149-
JrtClassPath(release=None, closeableRegistry)
150-
.map(jrt=>AggregateClassPath(entries.drop(1).prepended(jrt)))
151-
.getOrElse(base)
149+
JrtClassPath(release=None, unsafe=None, closeableRegistry)match {
150+
case jrt::Nil=>AggregateClassPath(entries.drop(1).prepended(jrt))
151+
case _=> base
152+
}
152153
case _=> base
153154
}
154155

‎src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala‎

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ package scala.tools.nsc.classpath
1414

1515
importjava.io.{Closeable,File}
1616
importjava.net.{URI,URL}
17+
importjava.nio.file._
1718

18-
importscala.reflect.io.{AbstractFile,PlainFile,PlainNioFile}
19-
importscala.tools.nsc.util.{ClassPath,ClassRepresentation,EfficientClassPath}
20-
importFileUtils._
2119
importscala.jdk.CollectionConverters._
2220
importscala.reflect.internal.JDK9Reflectors
21+
importscala.reflect.io.{AbstractFile,PlainFile,PlainNioFile}
2322
importscala.tools.nsc.CloseableRegistry
2423
importscala.tools.nsc.classpath.PackageNameUtils.{packageContains,separatePkgAndClassNames}
24+
importscala.tools.nsc.util.{ClassPath,ClassRepresentation,EfficientClassPath}
25+
importscala.util.Properties.{isJavaAtLeast,javaHome}
26+
importFileUtils._
2527

2628
/**
2729
* A trait allowing to look for classpath entries in directories. It provides common logic for
@@ -129,12 +131,10 @@ trait JFileDirectoryLookup[FileEntryType <: ClassRepresentation] extends Directo
129131
}
130132

131133
objectJrtClassPath {
132-
importjava.nio.file._,java.net.URI
133134
privatevaljrtClassPathCache=newFileBasedCache[Unit,JrtClassPath]()
134135
privatevalctSymClassPathCache=newFileBasedCache[String,CtSymClassPath]()
135-
defapply(release:Option[String],closeableRegistry:CloseableRegistry):Option[ClassPath]= {
136-
importscala.util.Properties._
137-
if (!isJavaAtLeast("9"))None
136+
defapply(release:Option[String],unsafe:Option[List[String]],closeableRegistry:CloseableRegistry):List[ClassPath]=
137+
if (!isJavaAtLeast("9"))Nil
138138
else {
139139
// TODO escalate errors once we're sure they are fatal
140140
// I'm hesitant to do this immediately, because -release will still work for multi-release JARs
@@ -145,28 +145,52 @@ object JrtClassPath {
145145

146146
valcurrentMajorVersion:Int=JDK9Reflectors.runtimeVersionMajor(JDK9Reflectors.runtimeVersion()).intValue()
147147
releasematch {
148-
caseSome(v)if v.toInt< currentMajorVersion=>
149-
try {
150-
valctSym=Paths.get(javaHome).resolve("lib").resolve("ct.sym")
151-
if (Files.notExists(ctSym))None
152-
else {
153-
valclassPath= ctSymClassPathCache.getOrCreate(v, ctSym::Nil, ()=>newCtSymClassPath(ctSym, v.toInt), closeableRegistry,true)
154-
Some(classPath)
155-
}
156-
}catch {
157-
case_:Throwable=>None
148+
caseSome(version)if version.toInt< currentMajorVersion=>
149+
valct= createCt(version, closeableRegistry)
150+
unsafematch {
151+
caseSome(pkgs)=>
152+
valopen=if (pkgs.isEmpty)List("sun.misc")else pkgs
153+
valjrts= createJrt(closeableRegistry)
154+
if (jrts.isEmpty) ct
155+
else ct.appended(newFilteringJrtClassPath(jrts.head,open:_*))
156+
case _=> ct
158157
}
159158
case _=>
160-
try {
161-
valfs=FileSystems.getFileSystem(URI.create("jrt:/"))
162-
valclassPath= jrtClassPathCache.getOrCreate((),Nil, ()=>newJrtClassPath(fs), closeableRegistry,false)
163-
Some(classPath)
164-
}catch {
165-
case_:ProviderNotFoundException|_:FileSystemNotFoundException=>None
166-
}
159+
createJrt(closeableRegistry)
167160
}
168161
}
169-
}
162+
privatedefcreateCt(v:String,closeableRegistry:CloseableRegistry):List[ClassPath]=
163+
try {
164+
valctSym=Paths.get(javaHome).resolve("lib").resolve("ct.sym")
165+
if (Files.notExists(ctSym))Nil
166+
else {
167+
valclassPath= ctSymClassPathCache.getOrCreate(v, ctSym::Nil, ()=>newCtSymClassPath(ctSym, v.toInt), closeableRegistry, checkStamps=true)
168+
List(classPath)
169+
}
170+
}catch {
171+
case_:Throwable=>Nil
172+
}
173+
privatedefcreateJrt(closeableRegistry:CloseableRegistry):List[JrtClassPath]=
174+
try {
175+
valfs=FileSystems.getFileSystem(URI.create("jrt:/"))
176+
valclassPath= jrtClassPathCache.getOrCreate((),Nil, ()=>newJrtClassPath(fs), closeableRegistry, checkStamps=false)
177+
List(classPath)
178+
}catch {
179+
case_:ProviderNotFoundException|_:FileSystemNotFoundException=>Nil
180+
}
181+
}
182+
183+
finalclassFilteringJrtClassPath(delegate:JrtClassPath,allowed:String*)extendsClassPathwithNoSourcePaths {
184+
privatevalallowedPackages= allowed
185+
privatedefpackagePrefix(p:String,q:String)= p.startsWith(q)&& (p.length== q.length|| p.charAt(q.length)=='.')
186+
privatedefok(pkg:PackageName)= pkg.dottedString.isEmpty|| allowedPackages.exists(packagePrefix(_, pkg.dottedString))
187+
defasClassPathStrings:Seq[String]= delegate.asClassPathStrings
188+
defasURLs:Seq[java.net.URL]= delegate.asURLs
189+
private[nsc]defclasses(inPackage:PackageName)=if (ok(inPackage)) delegate.classes(inPackage)elseNil
190+
deffindClassFile(className:String)=if (ok(PackageName(separatePkgAndClassNames(className)._1))) delegate.findClassFile(className)elseNone
191+
private[nsc]defhasPackage(pkg:PackageName)= ok(pkg)&& delegate.hasPackage(pkg)
192+
private[nsc]deflist(inPackage:PackageName)=if (ok(inPackage)) delegate.list(inPackage)elseClassPathEntries(Nil,Nil)
193+
private[nsc]defpackages(inPackage:PackageName)=if (ok(inPackage)) delegate.packages(inPackage)elseNil
170194
}
171195

172196
/**
@@ -177,8 +201,7 @@ object JrtClassPath {
177201
*
178202
* The implementation assumes that no classes exist in the empty package.
179203
*/
180-
finalclassJrtClassPath(fs: java.nio.file.FileSystem)extendsClassPathwithNoSourcePaths {
181-
importjava.nio.file.Path,java.nio.file._
204+
finalclassJrtClassPath(fs:FileSystem)extendsClassPathwithNoSourcePaths {
182205
typeF=Path
183206
privatevaldir:Path= fs.getPath("/packages")
184207

@@ -246,7 +269,7 @@ final class CtSymClassPath(ctSym: java.nio.file.Path, release: Int) extends Clas
246269
// e.g. "java.lang" -> Seq(/876/java/lang, /87/java/lang, /8/java/lang))
247270
privatevalpackageIndex: scala.collection.Map[String, scala.collection.Seq[Path]]= {
248271
valindex= collection.mutable.AnyRefMap[String, collection.mutable.ListBuffer[Path]]()
249-
valisJava12OrHigher=scala.util.Properties.isJavaAtLeast("12")
272+
valisJava12OrHigher= isJavaAtLeast("12")
250273
rootsForRelease.foreach(root=>Files.walk(root).iterator().asScala.filter(Files.isDirectory(_)).foreach { p=>
251274
valmoduleNamePathElementCount=if (isJava12OrHigher)1else0
252275
if (p.getNameCount> root.getNameCount+ moduleNamePathElementCount) {

‎src/compiler/scala/tools/nsc/settings/ScalaSettings.scala‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett
264264

265265
valYoutline=BooleanSetting ("-Youtline","Don't compile method bodies. Use together with `-Ystop-after:pickler` to generate the pickled signatures for all source files.").internalOnly()
266266

267+
valunsafe=MultiStringSetting("-Yunsafe","packages","Expose platform packages under --release")
267268
valexposeEmptyPackage=BooleanSetting ("-Yexpose-empty-package","Internal only: expose the empty package.").internalOnly()
268269
valYdelambdafy=ChoiceSetting ("-Ydelambdafy","strategy","Strategy used for translating lambdas into JVM code.",List("inline","method"),"method")
269270

‎src/compiler/scala/tools/util/PathResolver.scala‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,9 @@ final class PathResolver(settings: Settings, closeableRegistry: CloseableRegistr
257257

258258
// Assemble the elements!
259259
defbasis=List[Iterable[ClassPath]](
260-
jrt// 0. The Java 9+ classpath (backed by the ct.sym or jrt:/ virtual system, if available)
261-
.filter(_=>!settings.javabootclasspath.isSetByUser),// respect explicit `-javabootclasspath rt.jar`
260+
if (settings.javabootclasspath.isSetByUser)// respect explicit `-javabootclasspath rt.jar`
261+
Nil
262+
else jrt,// 0. The Java 9+ classpath (backed by the ct.sym or jrt:/ virtual system, if available)
262263
classesInPath(javaBootClassPath),// 1. The Java bootstrap class path.
263264
contentsOfDirsInPath(javaExtDirs),// 2. The Java extension class path.
264265
classesInExpandedPath(javaUserClassPath),// 3. The Java application class path.
@@ -269,7 +270,7 @@ final class PathResolver(settings: Settings, closeableRegistry: CloseableRegistr
269270
sourcesInPath(sourcePath)// 7. The Scala source path.
270271
)
271272

272-
privatedefjrt:Option[ClassPath]=JrtClassPath.apply(settings.releaseValue, closeableRegistry)
273+
privatedefjrt:List[ClassPath]=JrtClassPath.apply(settings.releaseValue, settings.unsafe.valueSetByUser, closeableRegistry)
273274

274275
lazyvalcontainers= basis.flatten.distinct
275276

‎test/files/neg/unsafe.check‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
unsafe.scala:9: error: value threadId is not a member of Thread
2+
def f(t: Thread) = t.threadId
3+
^
4+
1 error

‎test/files/neg/unsafe.scala‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
// scalac: --release:8 -Yunsafe:java.lang
3+
// javaVersion: 19+
4+
5+
// -Yunsafe opens packages but does not override class definitions
6+
// because ct.sym comes first
7+
8+
classC {
9+
deff(t:Thread)= t.threadId
10+
}

‎test/files/pos/unsafe.scala‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
// scalac: --release:8 -Yunsafe
3+
4+
importsun.misc.Unsafe
5+
6+
classC {
7+
valf=classOf[Unsafe].getDeclaredField("theUnsafe")
8+
f.setAccessible(true)
9+
valunsafe= f.get(null).asInstanceOf[Unsafe]
10+
11+
valk= unsafe.allocateInstance(classOf[K]).asInstanceOf[K]
12+
assert(k.value==0)
13+
}
14+
15+
classK {
16+
valvalue=42
17+
}
18+
19+
objectTestextendsApp {
20+
newC
21+
}

‎test/junit/scala/tools/nsc/classpath/JrtClassPathTest.scala‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class JrtClassPathTest {
2727
valelements=newClassPathFactory(settings, closeableRegistry).classesInPath(resolver.Calculated.javaBootClassPath)
2828
AggregateClassPath(elements)
2929
}
30-
elseJrtClassPath(None, closeableRegistry).get
30+
elseJrtClassPath(None,None,closeableRegistry).head
3131

3232
assertEquals(Nil, cp.classes(""))
3333
assertTrue(cp.packages("java").toString, cp.packages("java").exists(_.name=="java.lang"))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp