summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2010-04-13 22:51:04 +0000
committerIulian Dragos <jaguarul@gmail.com>2010-04-13 22:51:04 +0000
commitd95eb2a8f979b9f9db98a0e097ef3793674e57ab (patch)
tree6e11ba6e02cdd30c53861d42e6e52d5ce34b8d95 /src/compiler
parentc272bbfb64b1d0522e09daa0981a4942f63607a4 (diff)
downloadscala-d95eb2a8f979b9f9db98a0e097ef3793674e57ab.tar.gz
scala-d95eb2a8f979b9f9db98a0e097ef3793674e57ab.tar.bz2
scala-d95eb2a8f979b9f9db98a0e097ef3793674e57ab.zip
Made the icode reader more resilient to errors.
symbol does not cause any crashes, but the method using an unknown symbol will not be used for inlining. Resurrected tests, removed spec-matrix for the moment. No review.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala23
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala82
2 files changed, 66 insertions, 39 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 3a8d93a7a7..c78664bc19 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -221,9 +221,14 @@ abstract class ClassfileParser {
val ownerTpe = getClassOrArrayType(in.getChar(start + 1))
if (settings.debug.value)
log("getMemberSymbol(static: " + static + "): owner type: " + ownerTpe + " " + ownerTpe.typeSymbol.originalName)
- val (name, tpe) = getNameAndType(in.getChar(start + 3), ownerTpe)
+ val (name0, tpe0) = getNameAndType(in.getChar(start + 3), ownerTpe)
if (settings.debug.value)
- log("getMemberSymbol: name and tpe: " + name + ": " + tpe)
+ log("getMemberSymbol: name and tpe: " + name0 + ": " + tpe0)
+
+ forceMangledName(tpe0.typeSymbol.name, false)
+ val (name, tpe) = getNameAndType(in.getChar(start + 3), ownerTpe)
+// println("new tpe: " + tpe + " at phase: " + phase)
+
if (name == nme.MODULE_INSTANCE_FIELD) {
val index = in.getChar(start + 1)
val name = getExternalName(in.getChar(starts(index) + 1))
@@ -240,9 +245,10 @@ abstract class ClassfileParser {
f = owner.info.member(newTermName(origName.toString + nme.LOCAL_SUFFIX)).suchThat(_.tpe =:= tpe)
if (f == NoSymbol) {
// if it's an impl class, try to find it's static member inside the class
- if (ownerTpe.typeSymbol.isImplClass)
+ if (ownerTpe.typeSymbol.isImplClass) {
+// println("impl class, member: " + owner.tpe.member(origName) + ": " + owner.tpe.member(origName).tpe)
f = ownerTpe.member(origName).suchThat(_.tpe =:= tpe)
- else {
+ } else {
log("Couldn't find " + name + ": " + tpe + " inside: \n" + ownerTpe)
f = if (tpe.isInstanceOf[MethodType]) owner.newMethod(owner.pos, name).setInfo(tpe)
else owner.newValue(owner.pos, name).setInfo(tpe).setFlag(MUTABLE)
@@ -384,11 +390,14 @@ abstract class ClassfileParser {
* flatten would not lift classes that were not referenced in the source code.
*/
def forceMangledName(name: Name, module: Boolean): Symbol = {
- val parts = name.toString.split(Array('.', '$'))
+ val parts = name.decode.toString.split(Array('.', '$'))
var sym: Symbol = definitions.RootClass
atPhase(currentRun.flattenPhase.prev) {
- for (part0 <- parts; val part = newTermName(part0)) {
- val sym1 = sym.info.decl(part.encode)//.suchThat(module == _.isModule)
+ for (part0 <- parts; if !(part0 == ""); val part = newTermName(part0)) {
+ val sym1 = atPhase(currentRun.icodePhase) {
+ sym.linkedClassOfClass.info
+ sym.info.decl(part.encode)
+ }//.suchThat(module == _.isModule)
if (sym1 == NoSymbol)
sym = sym.info.decl(part.encode.toTypeName)
else
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 92dfb3749a..e129737ebd 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -99,26 +99,34 @@ abstract class ICodeReader extends ClassfileParser {
val owner = getOwner(jflags)
val dummySym = owner.newMethod(owner.pos, name).setFlag(javaToScalaFlags(jflags))
- var tpe = pool.getType(dummySym, in.nextChar)
-
- if ("<clinit>" == name.toString)
- (jflags, NoSymbol)
- else {
- val owner = getOwner(jflags)
- var sym = owner.info.member(name).suchThat(old => sameType(old.tpe, tpe));
- if (sym == NoSymbol)
- sym = owner.info.member(newTermName(name.toString + nme.LOCAL_SUFFIX)).suchThat(old => old.tpe =:= tpe);
- if (sym == NoSymbol) {
- log("Could not find symbol for " + name + ": " + tpe + " in " + owner.info.decls)
- log(owner.info.member(name).tpe + " : " + tpe)
- if (field)
- sym = owner.newValue(owner.pos, name).setInfo(tpe).setFlag(MUTABLE | javaToScalaFlags(jflags))
- else
- sym = dummySym.setInfo(tpe)
- owner.info.decls.enter(sym)
- log("added " + sym + ": " + sym.tpe)
+ try {
+ val ch = in.nextChar
+ var tpe = pool.getType(dummySym, ch)
+
+ if ("<clinit>" == name.toString)
+ (jflags, NoSymbol)
+ else {
+ val owner = getOwner(jflags)
+ var sym = owner.info.member(name).suchThat(old => sameType(old.tpe, tpe));
+ if (sym == NoSymbol)
+ sym = owner.info.member(newTermName(name.toString + nme.LOCAL_SUFFIX)).suchThat(old => old.tpe =:= tpe);
+ if (sym == NoSymbol) {
+ log("Could not find symbol for " + name + ": " + tpe + " in " + owner.info.decls)
+ log(owner.info.member(name).tpe + " : " + tpe)
+ if (name.toString() == "toMap")
+ tpe = pool.getType(dummySym, ch)
+ if (field)
+ sym = owner.newValue(owner.pos, name).setInfo(tpe).setFlag(MUTABLE | javaToScalaFlags(jflags))
+ else
+ sym = dummySym.setInfo(tpe)
+ owner.info.decls.enter(sym)
+ log("added " + sym + ": " + sym.tpe)
+ }
+ (jflags, sym)
}
- (jflags, sym)
+ } catch {
+ case e: MissingRequirementError =>
+ (jflags, NoSymbol)
}
}
@@ -149,18 +157,25 @@ abstract class ICodeReader extends ClassfileParser {
override def parseMethod() {
val (jflags, sym) = parseMember(false)
- if (sym != NoSymbol) {
- log("Parsing method " + sym.fullName + ": " + sym.tpe);
- this.method = new IMethod(sym);
- this.method.returnType = toTypeKind(sym.tpe.resultType)
- getCode(jflags).addMethod(this.method)
- if ((jflags & JAVA_ACC_NATIVE) != 0)
- this.method.native = true
- val attributeCount = in.nextChar
- for (i <- 0 until attributeCount) parseAttribute()
- } else {
- if (settings.debug.value) log("Skipping non-existent method.");
- skipAttributes();
+ var beginning = in.bp
+ try {
+ if (sym != NoSymbol) {
+ log("Parsing method " + sym.fullName + ": " + sym.tpe);
+ this.method = new IMethod(sym);
+ this.method.returnType = toTypeKind(sym.tpe.resultType)
+ getCode(jflags).addMethod(this.method)
+ if ((jflags & JAVA_ACC_NATIVE) != 0)
+ this.method.native = true
+ val attributeCount = in.nextChar
+ for (i <- 0 until attributeCount) parseAttribute()
+ } else {
+ if (settings.debug.value) log("Skipping non-existent method.");
+ skipAttributes();
+ }
+ } catch {
+ case e: MissingRequirementError =>
+ in.bp = beginning; skipAttributes
+ if (settings.debug.value) log("Skipping non-existent method. " + e.msg);
}
}
@@ -187,12 +202,15 @@ abstract class ICodeReader extends ClassfileParser {
definitions.getClass(name)
} else if (name.endsWith("$")) {
val sym = forceMangledName(name.subName(0, name.length -1).decode, true)
+// println("classNameToSymbol: " + name + " sym: " + sym)
+ if (name.toString == "scala.collection.immutable.Stream$$hash$colon$colon$")
+ print("")
if (sym == NoSymbol)
definitions.getModule(name.subName(0, name.length - 1))
else sym
} else {
forceMangledName(name, false)
- definitions.getClass(name)
+ atPhase(currentRun.flattenPhase.next)(definitions.getClass(name))
}
if (sym.isModule)
sym.moduleClass