summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-01-22 19:05:46 +0000
committerPaul Phillips <paulp@improving.org>2011-01-22 19:05:46 +0000
commit647d23d801a14a2bdd5e740325ef7d099aea15d7 (patch)
treeeda85c1a0c676acbaa2679572bf692eaafa05d1e /src
parent2432afcc61db2b08ad66f5335c4c1b18afe9f36d (diff)
downloadscala-647d23d801a14a2bdd5e740325ef7d099aea15d7.tar.gz
scala-647d23d801a14a2bdd5e740325ef7d099aea15d7.tar.bz2
scala-647d23d801a14a2bdd5e740325ef7d099aea15d7.zip
Merge branch 'invalid-sig' of /scala/trunk
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala54
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/reflect/SigParser.scala15
3 files changed, 44 insertions, 27 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index df0220ffe3..fd210dd35e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -82,17 +82,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
*/
class BytecodeGenerator extends BytecodeUtil {
def debugLevel = settings.debuginfo.indexOfChoice
- import scala.tools.reflect.SigParser
- def verifySig(sym: Symbol, sig: String) = {
- val ok =
- if (sym.isMethod) SigParser verifyMethod sig
- else if (sym.isTerm) SigParser verifyType sig
- else SigParser verifyClass sig
-
- def label = if (ok) "[ OK ] " else "[BAD!] "
- if (settings.verbose.value || !ok)
- println(label + sym + " in " + sym.owner.skipPackageObject.fullName + "\n " + sig)
- }
val MIN_SWITCH_DENSITY = 0.7
val INNER_CLASSES_FLAGS =
@@ -523,6 +512,17 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
nannots
}
+ /** Run the signature parser to catch bogus signatures.
+ * XXX But we should not be generating bogus signatures!
+ * The ticket is #4067.
+ */
+ import scala.tools.reflect.SigParser
+ def isValidSignature(sym: Symbol, sig: String) = (
+ if (sym.isMethod) SigParser verifyMethod sig
+ else if (sym.isTerm) SigParser verifyType sig
+ else SigParser verifyClass sig
+ )
+
// @M don't generate java generics sigs for (members of) implementation
// classes, as they are monomorphic (TODO: ok?)
private def noGenericSignature(sym: Symbol) = (
@@ -543,17 +543,29 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
// println("addGenericSignature sym: " + sym.fullName + " : " + memberTpe + " sym.info: " + sym.info)
// println("addGenericSignature: "+ (sym.ownerChain map (x => (x.name, x.isImplClass))))
erasure.javaSig(sym, memberTpe) foreach { sig =>
- if (settings.Yverifysigs.value)
- verifySig(sym, sig)
+ /** Since we're using a sun internal class for signature validation,
+ * we have to allow for it not existing or otherwise malfunctioning:
+ * in which case we treat every signature as valid. Medium term we
+ * should certainly write independent signature validation.
+ */
+ if (!SigParser.isParserAvailable || isValidSignature(sym, sig)) {
+ val index = jmember.getConstantPool.addUtf8(sig).toShort
+ if (opt.verboseDebug)
+ atPhase(currentRun.erasurePhase) {
+ println("add generic sig "+sym+":"+sym.info+" ==> "+sig+" @ "+index)
+ }
+ val buf = ByteBuffer.allocate(2)
+ buf putShort index
+ addAttribute(jmember, tpnme.SignatureATTR, buf)
+ }
+ else {
+ val msg = "!! Suppressing invalid generic sig for %s in %s: %s".format(
+ sym, sym.owner.skipPackageObject.fullName, sig
+ )
- val index = jmember.getConstantPool.addUtf8(sig).toShort
- if (opt.verboseDebug)
- atPhase(currentRun.erasurePhase) {
- println("add generic sig "+sym+":"+sym.info+" ==> "+sig+" @ "+index)
- }
- val buf = ByteBuffer.allocate(2)
- buf putShort index
- addAttribute(jmember, tpnme.SignatureATTR, buf)
+ if (settings.Yverifysigs.value) Console.println(msg)
+ else log(msg)
+ }
}
}
}
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 464aedded1..e10abf6a0d 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -108,7 +108,7 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings {
val log = PhasesSetting ("-Ylog", "Log operations during")
val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.")
val Ynogenericsig = BooleanSetting ("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.")
- val Yverifysigs = BooleanSetting ("-Yverify-generics", "Validated generated generic signatures.")
+ val Yverifysigs = BooleanSetting ("-Yverify-generics", "Output a message when an invalid generic signature is suppressed.")
val noimports = BooleanSetting ("-Yno-imports", "Compile without any implicit imports.")
// Not actually doing anything, so disabled.
// val nopredefs = BooleanSetting ("-Yno-predefs", "Compile without any implicit predefined values.")
diff --git a/src/compiler/scala/tools/reflect/SigParser.scala b/src/compiler/scala/tools/reflect/SigParser.scala
index 7185082175..5d85778570 100644
--- a/src/compiler/scala/tools/reflect/SigParser.scala
+++ b/src/compiler/scala/tools/reflect/SigParser.scala
@@ -6,29 +6,34 @@
package scala.tools
package reflect
-import java.lang.reflect.GenericSignatureFormatError
+import java.lang.reflect.{ GenericSignatureFormatError, Method }
/** The usual reflection song and dance to avoid referencing
* any sun.* classes.
*/
class SigParser {
val SunSignatureParser = "sun.reflect.generics.parser.SignatureParser"
- lazy val makeMethod = Class.forName(SunSignatureParser) getMethod "make"
+ private lazy val makeMethod: Method =
+ try Class.forName(SunSignatureParser) getMethod "make"
+ catch { case t => null }
+
def make() = makeMethod.invoke(null).asInstanceOf[SignatureParserInterface]
private def wrap(op: => Any) =
try { op ; true }
catch { case _: GenericSignatureFormatError => false }
- def verifyClass(s: String) = wrap(make() parseClassSig s)
- def verifyMethod(s: String) = wrap(make() parseMethodSig s)
- def verifyType(s: String) = wrap(make() parseTypeSig s)
+ def isParserAvailable = makeMethod != null
+ def verifyClass(s: String) = isParserAvailable && wrap(make() parseClassSig s)
+ def verifyMethod(s: String) = isParserAvailable && wrap(make() parseMethodSig s)
+ def verifyType(s: String) = isParserAvailable && wrap(make() parseTypeSig s)
type ClassSignature <: AnyRef
type MethodTypeSignature <: AnyRef
type TypeSignature <: AnyRef
type SignatureParserInterface = {
+ def isParserAvailable: Boolean
def parseClassSig(s: String): ClassSignature
def parseMethodSig(s: String): MethodTypeSignature
def parseTypeSig(s: String): TypeSignature