Skip to content

Commit 043e390

Browse files
committed
Move code
1 parent 1b196c9 commit 043e390

File tree

2 files changed

+95
-98
lines changed

2 files changed

+95
-98
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import dotty.tools.dotc.ast.tpd
1313
import dotty.tools.dotc.ast.Trees
1414
import dotty.tools.dotc.core.Annotations.Annotation
1515
import dotty.tools.dotc.core.Constants._
16+
import dotty.tools.dotc.core.Contexts.Context
1617
import dotty.tools.dotc.core.Decorators._
1718
import dotty.tools.dotc.core.Flags
1819
import dotty.tools.dotc.core.Names.Name
@@ -22,6 +23,8 @@ import dotty.tools.dotc.core.StdNames._
2223
import dotty.tools.dotc.core.Symbols._
2324
import dotty.tools.dotc.core.Types
2425
import dotty.tools.dotc.core.Types._
26+
import dotty.tools.dotc.core.TypeErasure
27+
import dotty.tools.dotc.transform.GenericSignatures
2528

2629
/*
2730
* Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes.
@@ -450,16 +453,27 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
450453
} // end of trait BCAnnotGen
451454

452455
trait BCJGenSigGen {
456+
import int._
453457

454458
def getCurrentCUnit(): CompilationUnit
455459

456-
/* @return
457-
* - `null` if no Java signature is to be added (`null` is what ASM expects in these cases).
458-
* - otherwise the signature in question
460+
/**
461+
* Generates the generic signature for `sym` before erasure.
459462
*
460-
* must-single-thread
463+
* @param sym The symbol for which to generate a signature.
464+
* @param owner The owner of `sym`.
465+
* @return The generic signature of `sym` before erasure, as specified in the Java Virtual
466+
* Machine Specification, §4.3.4, or `null` if `sym` doesn't need a generic signature.
467+
* @see https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.4
461468
*/
462-
def getGenericSignature(sym: Symbol, owner: Symbol): String = int.getGenericSignature(sym, owner)
469+
def getGenericSignature(sym: Symbol, owner: Symbol): String = {
470+
ctx.atPhase(ctx.erasurePhase) {
471+
val memberTpe =
472+
if (sym.is(Flags.Method)) sym.denot.info
473+
else owner.denot.thisType.memberInfo(sym)
474+
getGenericSignatureHelper(sym, owner, memberTpe).orNull
475+
}
476+
}
463477

464478
} // end of trait BCJGenSigGen
465479

@@ -829,6 +843,82 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
829843
}
830844
}
831845
}
846+
847+
private def getGenericSignatureHelper(sym: Symbol, owner: Symbol, memberTpe: Type)(implicit ctx: Context): Option[String] = {
848+
if (needsGenericSignature(sym)) {
849+
val erasedTypeSym = TypeErasure.fullErasure(sym.denot.info).typeSymbol
850+
if (erasedTypeSym.isPrimitiveValueClass) {
851+
// Suppress signatures for symbols whose types erase in the end to primitive
852+
// value types. This is needed to fix #7416.
853+
None
854+
} else {
855+
val jsOpt = GenericSignatures.javaSig(sym, memberTpe)
856+
if (ctx.settings.XverifySignatures.value) {
857+
jsOpt.foreach(verifySignature(sym, _))
858+
}
859+
860+
jsOpt
861+
}
862+
} else {
863+
None
864+
}
865+
}
866+
867+
private def verifySignature(sym: Symbol, sig: String)(implicit ctx: Context): Unit = {
868+
import scala.tools.asm.util.CheckClassAdapter
869+
def wrap(body: => Unit): Unit = {
870+
try body
871+
catch {
872+
case ex: Throwable =>
873+
ctx.error(i"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName}
874+
|signature: $sig
875+
|if this is reproducible, please report bug at https://github.com/lampepfl/dotty/issues
876+
""".trim, sym.sourcePos)
877+
throw ex
878+
}
879+
}
880+
881+
wrap {
882+
if (sym.is(Flags.Method)) {
883+
CheckClassAdapter.checkMethodSignature(sig)
884+
}
885+
else if (sym.isTerm) {
886+
CheckClassAdapter.checkFieldSignature(sig)
887+
}
888+
else {
889+
CheckClassAdapter.checkClassSignature(sig)
890+
}
891+
}
892+
}
893+
894+
// @M don't generate java generics sigs for (members of) implementation
895+
// classes, as they are monomorphic (TODO: ok?)
896+
private final def needsGenericSignature(sym: Symbol): Boolean = !(
897+
// pp: this condition used to include sym.hasexpandedname, but this leads
898+
// to the total loss of generic information if a private member is
899+
// accessed from a closure: both the field and the accessor were generated
900+
// without it. This is particularly bad because the availability of
901+
// generic information could disappear as a consequence of a seemingly
902+
// unrelated change.
903+
ctx.base.settings.YnoGenericSig.value
904+
|| sym.is(Flags.Artifact)
905+
|| sym.isAllOf(Flags.LiftedMethod)
906+
|| sym.is(Flags.Bridge)
907+
)
908+
909+
private def getStaticForwarderGenericSignature(sym: Symbol, moduleClass: Symbol): String = {
910+
// scala/bug#3452 Static forwarder generation uses the same erased signature as the method if forwards to.
911+
// By rights, it should use the signature as-seen-from the module class, and add suitable
912+
// primitive and value-class boxing/unboxing.
913+
// But for now, just like we did in mixin, we just avoid writing a wrong generic signature
914+
// (one that doesn't erase to the actual signature). See run/t3452b for a test case.
915+
916+
val memberTpe = ctx.atPhase(ctx.erasurePhase) { moduleClass.denot.thisType.memberInfo(sym) }
917+
val erasedMemberType = TypeErasure.erasure(memberTpe)
918+
if (erasedMemberType =:= sym.denot.info)
919+
getGenericSignatureHelper(sym, moduleClass, memberTpe).orNull
920+
else null
921+
}
832922
}
833923

834924
object BCodeHelpers {

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -99,99 +99,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap
9999
if (found == null) None else Some(found)
100100
}
101101

102-
// @M don't generate java generics sigs for (members of) implementation
103-
// classes, as they are monomorphic (TODO: ok?)
104-
private final def needsGenericSignature(sym: Symbol): Boolean = !(
105-
// pp: this condition used to include sym.hasexpandedname, but this leads
106-
// to the total loss of generic information if a private member is
107-
// accessed from a closure: both the field and the accessor were generated
108-
// without it. This is particularly bad because the availability of
109-
// generic information could disappear as a consequence of a seemingly
110-
// unrelated change.
111-
ctx.base.settings.YnoGenericSig.value
112-
|| sym.is(Flags.Artifact)
113-
|| sym.isAllOf(Flags.LiftedMethod)
114-
|| sym.is(Flags.Bridge)
115-
)
116-
117-
private def verifySignature(sym: Symbol, sig: String)(implicit ctx: Context): Unit = {
118-
import scala.tools.asm.util.CheckClassAdapter
119-
def wrap(body: => Unit): Unit = {
120-
try body
121-
catch {
122-
case ex: Throwable =>
123-
ctx.error(i"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName}
124-
|signature: $sig
125-
|if this is reproducible, please report bug at https://github.com/lampepfl/dotty/issues
126-
""".trim, sym.sourcePos)
127-
throw ex
128-
}
129-
}
130-
131-
wrap {
132-
if (sym.is(Flags.Method)) {
133-
CheckClassAdapter.checkMethodSignature(sig)
134-
}
135-
else if (sym.isTerm) {
136-
CheckClassAdapter.checkFieldSignature(sig)
137-
}
138-
else {
139-
CheckClassAdapter.checkClassSignature(sig)
140-
}
141-
}
142-
}
143-
144-
/**
145-
* Generates the generic signature for `sym` before erasure.
146-
*
147-
* @param sym The symbol for which to generate a signature.
148-
* @param owner The owner of `sym`.
149-
* @return The generic signature of `sym` before erasure, as specified in the Java Virtual
150-
* Machine Specification, §4.3.4, or `null` if `sym` doesn't need a generic signature.
151-
* @see https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.4
152-
*/
153-
def getGenericSignature(sym: Symbol, owner: Symbol): String = {
154-
ctx.atPhase(ctx.erasurePhase) {
155-
val memberTpe =
156-
if (sym.is(Flags.Method)) sym.denot.info
157-
else owner.denot.thisType.memberInfo(sym)
158-
getGenericSignature(sym, owner, memberTpe).orNull
159-
}
160-
}
161-
162-
def getStaticForwarderGenericSignature(sym: Symbol, moduleClass: Symbol): String = {
163-
// scala/bug#3452 Static forwarder generation uses the same erased signature as the method if forwards to.
164-
// By rights, it should use the signature as-seen-from the module class, and add suitable
165-
// primitive and value-class boxing/unboxing.
166-
// But for now, just like we did in mixin, we just avoid writing a wrong generic signature
167-
// (one that doesn't erase to the actual signature). See run/t3452b for a test case.
168-
169-
val memberTpe = ctx.atPhase(ctx.erasurePhase) { moduleClass.denot.thisType.memberInfo(sym) }
170-
val erasedMemberType = TypeErasure.erasure(memberTpe)
171-
if (erasedMemberType =:= sym.denot.info)
172-
getGenericSignature(sym, moduleClass, memberTpe).orNull
173-
else null
174-
}
175-
176-
private def getGenericSignature(sym: Symbol, owner: Symbol, memberTpe: Type)(implicit ctx: Context): Option[String] =
177-
if (needsGenericSignature(sym)) {
178-
val erasedTypeSym = TypeErasure.fullErasure(sym.denot.info).typeSymbol
179-
if (erasedTypeSym.isPrimitiveValueClass) {
180-
// Suppress signatures for symbols whose types erase in the end to primitive
181-
// value types. This is needed to fix #7416.
182-
None
183-
} else {
184-
val jsOpt = GenericSignatures.javaSig(sym, memberTpe)
185-
if (ctx.settings.XverifySignatures.value) {
186-
jsOpt.foreach(verifySignature(sym, _))
187-
}
188-
189-
jsOpt
190-
}
191-
} else {
192-
None
193-
}
194-
195102
extension symExtensions on (sym: Symbol) {
196103

197104
def isInterface: Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait)

0 commit comments

Comments
 (0)